What are the requirements for SQLCipher passphrase? - passwords

Are there any requirements for SQLCipher passphrase? For example, minimum and maximum number of symbols, invalid symbols, etc.

There are no requirements for a SQLCipher passphrase. By default SQLCipher keys undergo a key derivation process with 256000 iterations of PBKDF2-HMAC-SHA512 which is used to convert the passphrase to the encryption key used for the database. This helps protect against brute force and dictionary attacks. However, if an application wants to enforce a specific passphrase validation process it must implement that logic itself.

Related

How to store encryption key?

I look out many password managers like keeper, 1password, secret-in and I am following secret-in password manager to create my own project and trying to add same features, but got stuck at storing the data of users like his/her secrets, payment secrets in encrypted form. I read encryption model of keeper here but still didn't understand. Where to store a server side encryption key?
I have some data that is symmetrically encrypted with a single key in my database. Rather than hard coding it into my code, I am looking for a safer way to store the encryption key. Where can I safely store it?
The approach here is quite simple.
You only send encrypted data to the server for storage/backup.
The encrypted data received doesn't come with a key.
You need to ensure all encryption and decryption occurs locally on the users device. Thus the user needs to supply the key.
Users aren't good at providing high quality key material, so instead, require the user to provide a password, take that password and pass it through a hash-based key derivation function with parameters that make the function slow (high ops, high mem requirements). An algorithm like pbkdf2 with a strong PRF like HMAC-SHA-2 should be sufficient.
Update:
To answer your specific questions, you need to perform the following steps, you will need to use a cryptographic library that supports key derivation from password and symmetric encryption, like libsodium.
request password from user on first use
run this password through key derivation to derive a key from it: https://libsodium.gitbook.io/doc/key_derivation
execute encryption of user data with key: https://libsodium.gitbook.io/doc/secret-key_cryptography
destroy the key and send data to server for backup

Transforming a password to a 256-bit key

I have a file encrypted with AES using a 256-bit (or 128-bit) key. Passing to and asking the file owner to keep the 256-bit key would be humanly difficult.
How can a more friendly password be used by the owner to remember or retrieve the actual 256-bit key?
For this kind of issues, we have Key Derivation Functions (KDF), as Argon2, PBKDF2, or BCrypt. Argon2 was the winner of Password Hashing Competition. You can see a detailed answer in crypto.stackexchange
In your case, first, you need to choose a password, and use it to generate a key by a KDF for the AES encryption then use this key to encrypt. Depend on the security you may use the random input to increase the entropy, though it will be hard to remember, too.
You can also encode the AES key into base64, however, it will not be easily remembered either.
Note: you can also transfer it with a small Veracrypt Volume.

C# CryptoGraphy AES key generate?

I have a question about when AES generate a key and IV how would the user know what the key is or how the program would know which key to use like it is generated. For example like if there is a encryption method that encrypt the file and generate the key and IV. When the program restarts or be used another day they would want to use the decryption but how would you know or the program knows thats the key for that file.
I understand the decryption and encryption by looking at it. I just dont know where the information is store to retrieve the key?
Key management is a large part of any cryptography related protocol. It takes a book or so to explain.
One of the most known methods is using a password (see password based encryption in PKCS#5, where a key is generated from a (stored) salt, number of iterations and of course the password (encoded to bytes). Another option is to store the key on some removable device like an USB key.
Usually the main key is not used to encrypt the data, but an intermediate key called the data or session key is used. For instance PGP encryption generates a data key and encrypts it with a public key of an asymmetric key pair.
Then there are smart cards, TPM modules, HSM's, key containers (possibly provided by the OS), key sharing protocols etc. etc. etc..
So ... it depends.
Sometimes it is easier to think of a key as another secret. By encrypting something you've only "compressed" your larger secret (your plaintext) into a smaller secret (the key) that you have to keep and manage. This secret however may have been generated in advance, or may have been generated by other means. If you just generate your key at the same time and location as your ciphertext, you haven't solved anything yet, you only made your secret smaller.
It's easier for the IV, the IV can simply be stored with (commonly, in front of) the ciphertext.

Cryptographic Agility and Key Management

I have a design question. I have a web application that uses .NET encryption APIs to encrypt/decrypt data. (App uses old crypto algorithms like MD5 and SHA-1). Also, app hard-codes the encryption keys in the production code.
I would like to;
1 ) Update existing old algorithms (MD5 and SHA-1) to new ones.
2 ) Move encryption keys from source code to a secure share.
3 ) Can change the encryption keys easily and regularly
My Design;
Algorithm Update
For the algorithm update, we use specific .NET implementations of crypto algorithms. We use classes like MD5CryptoProvider or RijndaelManaged. These are all hard-coded. I am going to remove the specific algorithm dependency and make it more agile like;
HashAlgorithm algo = HashAlgorithm.Create(MyPreferredHash.ToString());
algo.ComputeHash(...);
MyPreferredHash value will be loaded from a config file so that we can change this when we want to.
Question: Upgrading the code is easy to do this. However do you see any potential issues with changing crypto algorithms? We do not store any encrypted or hash data anywhere and web application is stateless. All the hash values are generated and appended to url strings and decrypted from another pages. Therefore, no data is stored. Except the cookies. When we encrypt cookie and send it back to user, we decrypt it when server receives it. In this case, i thought of destroying the cookie and send a new one to the client. Is this reasonable? Any other issues you think of ?
Key Management
Second part of the design, is to remove hard-coded keys from source code to secure share. After this, I need to be able to rollout new encryption keys. Each encryption key will be associated with a expire date. When we rollout a new encryption key, new key will be used for encryption and decryption. If it fails to decrypt, then we can try old keys. Old keys will be used for decryption or verification until their expire date. When they pass their expire date, they should retire.
For the storage; I am thinking of storing the encryption keys in a config file in the local machine as "encrypted" by a master key which will reside in a secure share. Therefore, anybody who doesn't have access to this secure share will not be able to see the master key. Master key will be loaded from secure share to machine registry when a machine reboots. The encryption keys in the local machine will be loaded from config file (local) and decrypted by master key in registry.
This storage choice will give us storing only one master key in a secure share and also historical changes to the encryption keys as we will store them in version control system.
The challenging part is the key change/update.
What is the recommended key change algorithm here for a distributed web application? If we are doing partial deployment after a release, not all the machines will have the same config file content (e.g. new encryption key added). All site deployment can take 1-2 weeks. This is also another concern that if we should wait for all deployments complete so that these keys will be active after that.
Any other feedback?
You are quite right to design your app to be agile in the face of unknown future attacks on particular encryption algorithms.
The simplest way to future-proof your app in a robust way would seem to be to switch to using a standard data format for your encrypted information, and use a standard library to do the hard lifting. The choice of a specific standard to use would depend on what kind of data formats you're working with, but there are good candidates to choose from. Then when there is a future attack, you can just change some parameters, or update to the latest version of the implementation.
Doing crypto is very tricky. Best to leave it up to the experts.

Would there be any problems using private/public key encryption for saving a password?

Using hashing algorithms like md5 we suffer from a limited entropy which means that very long passwords might result in hashes that can be regenerated by a shorter password.
I was thus wondering if it would be a good idea to store a password encrypted with the public key of public/private key encryption on the server. As decrypting is not needed, one could just throw away the secret key to avoid losing passwords when the server is compromised.
However, this method does not seem to be used widely. So are there drawbacks? If yes, then which?
There are several drawbacks. Among them:
You now have a token which must be protected. If someone gets your secret key, they have every password that was encrypted with that key. Asymmetric encryption is less of an issue if you "lose" the private key, but you better pray all copies of it are gone. Hashes can't be decrypted, period.
An encrypted password can be pretty much any length, and thus would require a pretty large field in the database (or length limits for the plaintext) in order to be stored. Hashes have a known length.
If you can decrypt the password, you know it. If ever there was a problem with someone using that password to break into something else, everyone who knew that password belonged to that user is a suspect. That now means you. Even if you use one-way encryption as a hash, you'd better be able to prove you can't decrypt it -- and then, if you don't want to decrypt it, why encrypt?
Generally, you'd only choose encryption over hashing when you have to know the password for something else -- like, say, when you're using it to log in to another system on behalf of the user. And ideally, you'd exhaust all other possibilities first.
Well there is always the drawback that computing a cryptographic hash is much less costly than encrypting a tiny password with a public-key encryption algorithm.
Secondly, you still suffer from limited entropy with public-key encryption, your bit string will still be limited. If you need more bits, use a hash with a bigger internal state (SHA-512, Whirlpool, etc...)
Third, you would need to store the public key along with the password, which results in a pretty hefty storage cost (considering how big public keys are), and if you're thinking of using the same public key for all passwords, don't - if that key is compromised it's over.
Also another consideration: without a password size limit there's a chance even padded block encryption will result in different storage sizes for different passwords, which can make database indexing a hell of a lot more difficult (probably not a huge concern but to keep in mind).
And finally, the biggie - hashes are meant to unequivocally destroy all structure in the input data, which is exactly what you want when storing passwords for verification. Encryption algorithms don't do that - they transform the data to make it unintelligible without the proper key, which sort of goes against what you're trying to use it for.
So, no, this method should not be used because it is self-defeating. Use a hash with a bigger internal state.