0
$\begingroup$

I am making a program for personal use that will not contain super-sensitive information. I am using this to explore cryptography. Would it be acceptable to use a password to generate a key for AES, or should I make a file, store it somewhere separate of the program, and call it for encryption/decryption. If the password is too short to be an AES key, should I hash it or pad it?

I just realized that I could link to my stack overflow account! I am sorry if this question is misplaced.

$\endgroup$
3
$\begingroup$

You cannot assume that a text-based input is an acceptable replacement for a key in cryptographic algorithms. The default assumption used to design algorithms is that the key is generated randomly; specifically, generated in such a way that the key is unpredictable and comes from a uniform random distribution of all possible keys.

If you use text instead of random bits there are plenty of problems:

  • You reduce the number of keys that need to be tested
  • Your input will have patterns that may make your key more likely to belong to a class of weak keys. If a set of weak keys exists for an algorithm, using one of them will cause the algorithm to exhibit biases that could make it insecure.
  • Passwords chosen by humans are far more predictable than the typical person assumes. If you need to keep encrypted data safe then you need to be smart with your password.
  • A password might be shorter or longer than an algorithm's normal key size. (Padding and truncating here is a bad idea, especially when password- based key derivation functions exist.)

How one might (correctly) encrypt a file using a password:

  1. Generate a new random password not used for any online services (or otherwise shared with anyone). How do you do that?
    • Don't use things like your favorite sports team or a birth date.
    • Generate a random string of characters from something like /dev/urandom. A string, if the length is $n$ and the characters come from an alphabet of size $m$, has up to $\log_2(m^n) = n \log_2(m)$ bits of entropy
    • Generate a string of $n$ random words from a dictionary of $m$ words, using spaces or periods or commas as word separators. This also has $n \log_2(m)$ bits of entropy.
    • If you want to generate a memorable password, no computer required, and you have a fair six-sided die, then use Diceware. I recommend one of the EFF lists over the original word list.
    • Make sure your password has enough entropy to prevent brute force guessing. The minimum you want is probably 100 bits. Some might say 80 bits or 128 bits. (When you generate a password for websites you can go much lower, but that's because it's a different application of passwords.)
  2. Generate a nonce
  3. Use a key derivation function. For example, scrypt if (you commit to using a lot of RAM), bcrypt, or Argon2d. The functions I listed accept passwords as input and "stretch" them. They make brute force guessing harder by making the attacker and the person who has legitimate access to the file do extra work. Use it to derive a symmetric key of 256 bits (if it's available even if entropy isn't 256 bits and you fear quantum computing) otherwise choose a key size and algorithm with at least 128 bit security level.
  4. Create an output file, store the nonce in plaintext, then append the ciphertext and authentication tag of the encrypted input file to the output file.
  5. Remove data from the original plaintext file from any storage place or memory where someone could gain access to it.

To decrypt a file use the same key derivation function, check that the authentication tag is correct, and decrypt the data using the nonce and key.

There are some details and warnings I am leaving out because they're answered in other questions here, at http://security.stackexchange.com/ and on many other websites.

$\endgroup$
  • $\begingroup$ So, with this method, I would not add a password/passphrase check? I was planing on using BCrypt to hash my password and check the hashes. Would it be "acceptable" to just use the users password (lets say 7000 word library diceware to choose six words) and hash it to make a key to attempt to decrypt file. Then test if the first line is correct? The first line is a title line I.E. "Number Description" and all other lines are lists following the format of the title line. $\endgroup$ – Take That 101 May 22 '18 at 1:01
  • $\begingroup$ @TakeThat101 Use authenticated encryption. Use bcrypt (with bcrypt specific precautions) to derive a key. If you derive the wrong key (because you have the wrong password) then authentication will fail. It's not necessary to check the password itself. Checking one line of a file does not determine if the rest of the file is uncorrupted. Cryptographic message authentication does. $\endgroup$ – Future Security May 22 '18 at 1:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.