Transforming a password to a 256-bit key - cryptography

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.

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

What are the requirements for SQLCipher passphrase?

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.

What's the point of encryption if there exists decryption?

Let's say in database user password is encrypting in MD5 and it's no more readable by human, but i can copy MD5 hash and go to any website which provide MD5 decryption and get actually password. So am I missing something?
MD5 is a one-way operation (hashing), it is not possible to decrypt it. But you can hash a lot of passwords and check whether the hashes are the same (brute-forcing). When you find a match, you can not know if that was the original password though, because many other passwords result in the same hash (collisions).
Mitigating brute-forcing and other cracking techniques is the goal of password-hash functions like BCrypt, SCrypt, PBKDF2 or Argon2. Absolutely use them instead of MD5 and you will see, that there exists no websites offering "decryption".

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.

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.