I am writing a small personal project where I would like to use AES to encrypt some documents. It seems to work pretty well, but I was wondering about one point of my code. The current structure is user inputs password -> key = sha256(password) -> compress(key) -> AES(document, key). Where compress XORs the key with itself. So for 128 bit AES the first half is XORed with the second to get a 128bit key. I do a similar operation for 192 bit AES. I have a few questions about this:

  1. Is it safe? If not, could I just drop the extra bits?
  2. Is there a better way to go from a password to a key? I think for the average password entropy is pretty low.
  3. Could I use this method to generate an IV for some other block cipher mode?
  • $\begingroup$ 1. Just drop them, though it should be safe to xor it is less common. 2. Yes, many better ways, look up "key derivation function" (kdf) such as scrypt and argon. 3. Yes, most KDFs allow you to generate a configurable length output. $\endgroup$ – Thomas M. DuBuisson Dec 1 '17 at 15:25
  • $\begingroup$ I think the issue is the sha256 with a user-supplied input. Using a KDF with higher computational cost, such as Argon2 or at least the PBKDF2, can be better. $\endgroup$ – Inkeliz Dec 1 '17 at 15:48
  1. Someone else should chime in here just to be sure, but as far as I know truncating SHA256 is "safe", in the sense that it would be as good as any other "safe" 128 bit hash. I don't think XORing helps in any way, dropping the bits is probably better. Your application of a truncated SHA256, however, is not safe.

  2. Yes, there is absolutely a better way. Like you said, average password entropy is low. Your key therefore has low entropy. Brute forcing a low entropy key is easy, when the key derivation is a simple SHA256 round. You need to use a specialized password hashing function. SHA256 is designed to be fast, you need a function that is designed to resist such brute force attacks. Examples include Argon2, scrypt, and PBKDF2.

  3. This depends on the design. An IV should not be predictable. What kind of password would you be using to generate an IV? Would you use it multiple times? Are there reasons why you can't use a random IV?

| improve this answer | |
  • $\begingroup$ It's actually a good question to consider why xoring may not be safe, thinking about it I cannot think of a good reason. There is a large set values that would xor to the same thing but then so would truncated values... $\endgroup$ – user10653 Dec 1 '17 at 18:28
  • $\begingroup$ The XOR doesn't help, which is trivial in ROM (first half is perfect random, second half is perfect random, so output is perfect random). An IV should be random. It can be public, it doesn't matter, but having it depend on the password is at least fishy. Just generate 128 random bits and prepend them to the ciphertext. $\endgroup$ – Ruben De Smet Dec 1 '17 at 22:00
  • $\begingroup$ SHA-224 is basically SHA-256 with different (internal) start values and then truncating the SHA-256 hash. If truncating is not secure then SHA-224 would not be secure. Note that commonly the leftmost bits are used. I'd use those bytes if you want to comply to the principle of least surprise. $\endgroup$ – Maarten Bodewes Dec 1 '17 at 22:59

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.