Information Security Stack Exchange is a question and answer site for information security professionals. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm writing a desktop application where I'm using PBKDF2 to generate an encryption key to AES-128 encrypt the config file. The config file contains a crypo-random key that's been used to encrypt the data for the program. The user already entered that key as provided from us on installation. The idea is they enter the crypto random key once and then they can use an easier to remember password. So far so good.

So, when the user loads the program, they enter the password. We used the password to regenerate the PBKDF2 key and decrypt the config file.

Now, how do I easily verify that the user entered the correct password? Of course, if they entered an incorrect password, decryption of the data won't work. But I'd like to reject the password immediately rather than letting the program load and then the user gets a decryption error message box.

I've read that TrueCrypt encrypts a known constant, the string "TRUE" and then verifies that the password-based key will encrypt "TRUE" to the same ciphertext. I've also read about generating an HMAC-SHA hash to verify the encrypted data. But that you don't want to use the same key for the MAC and to encrypt the data. For this reason, I like TrueCrypt's method (I don't have to track two sets of salts and IVs). I don't really care if an attacker can load the program. They won't be able to read any data. I just don't want the user to get in with the wrong password and think the program is insecure.

What's the right way to do this?

share|improve this question
up vote 10 down vote accepted

It depends whether you want to defend against typing mistakes, or attacks.

If you just want to defend against typing mistakes, just include some structure in your configuration file. E.g., define that your configuration file MUST begin, when decrypted, with the string "This is configuration file for application FooBar". If you do not find that string upon decryption, then the key is wrong.

If you want to defend against attacks (a bad guy voluntarily alters parts of the encrypted configuration file to make you load an incorrect key), then you need something stronger. The "right" solution is to use an authenticated encryption mode (my favourite is EAX). If your programming framework does not include an implementation of EAX mode, you can do something like this:

  • From the user's passphrase, generate 384 bits of key (PBKDF2 is a "key derivation function", it can be used to produce keys of arbitrary length). Split these into three 128-bit keys K1, K2 and K3.
  • Encrypt the configuration file with AES-128-CBC, using K1 as key and K2 as IV. Call the result C (the encrypted file).
  • Compute a MAC value over C, using key K3. For the MAC function, use HMAC with SHA-256 (or SHA-1, but SHA-256 is preferred on a general basis). The MAC is stored along C (appended, as header, as a separate file... that's your choice).
  • When decrypted, to the reverse: obtain the three keys from PBKDF2, verify the MAC, and (only if the MAC was correct) decrypt the file.

This scheme would resist both attacks and typing mistakes (however, it does not distinguish between a wrong passphrase and a genuine attack).

Edit: I had left it implicit, but it would be better to state it plainly: since we are using PBKDF2, there is a salt which is used to turn the password into the PBKDF2 output. Each encrypted file SHALL have its own salt. The salt SHALL be encoded in the file header. If a file is "re-encrypted", a new random salt SHALL be generated.

share|improve this answer
A good answer. I recommend using authenticated encryption in any case (i.e., either EAX or Thomas's alternative suggestion). One of the most common mistakes is to use encryption without message authentication; that often leads to security vulnerabilities, so you should always use some form of authenticated encryption, any time you are encrypting. – D.W. Sep 3 '12 at 20:10
I'm not sure I agree with your authentication scheme for the encrypted method, but for now the first option suffices. Thanks! – John Sep 4 '12 at 13:27
"Encrypt the configuration file with AES-128-CBC, using K1 as key and K2 as IV. Call the result C (the encrypted file)." In this scheme this fixates IV, next encryption with same password yields same IV. Should we rather have random IV every time ? – boo9 Apr 11 '13 at 11:43
From the description of the problem, it appears that the configuration file is only ever encrypted once. – Stephen Touset Apr 11 '13 at 17:06
@boo9: it's my fault, I had left a bit implicit. Now fixed: the PBKDF2 salt must be file-specific (i.e. a new salt for each encryption, the salt is encoded in the file header). – Thomas Pornin Apr 11 '13 at 17:12

TrueCrypt's mechanism is probably the best option here. You can verify whether the password was correct after decrypting only a single block, and it requires no extra security considerations.

Introducing extra hashing and verification leaves you vulnerable to any weaknesses in those algorithms. In this case, you're relying solely on the security of your cipher, which you're also relying on to secure your data. If AES-128 is broken, having "TEST" incorrectly identified as valid is the least of your worries!

share|improve this answer
"If AES-128 is broken" - you mean if someone finds a vulnerability in the AES cipher that can be exploited to break encryption? If that ever happened it would destroy computer security... The "extra hashing" would by cryptographically secure according to accepted standards – John Sep 4 '12 at 13:29
@John My point is that if AES-128 is found to be broken in future, the fact that you're incorrectly validating the "TEST" string as correct would be the least of your worries, since your entire data is compromised. – Polynomial Sep 4 '12 at 13:54

@thomas "From the user's passphrase, generate 384 bits of key (PBKDF2 is a "key derivation function", it can be used to produce keys of arbitrary length). Split these into three 128-bit keys K1, K2 and K3..... "

Could we generate IVs randomy and dont use 'precious' PBKDF2 function for that ? e.g., use PBKDF2 with IV=0 to generate only 'secret' keys - K1,K2, K1 for encryption, K2 for MAC. And whenever we need an IV (and whatever many) we randomy generate it and store it in clear text in the file. Would this approach be less/more simple ? less/more secure ?

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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