I'm writing some software where I have to encrypt all files that are written to a specific folder using AES. There is one password/key that is configured somewhere, which is always used.

I don't want to store a base64 string because that is too complicated for the person who might have to change the configuration. I want to store a string containing any characters. What is the best way to convert this password to a key for use in AES?

  • Can I just get the bytes from the key?
  • Should I generate a key using PBKDF2?

As I understand, I then also need to provide a salt. However, in my situation, the salt seems unnecessary because I only have one key.

  • Do I just provide an empty salt or is that somehow not secure?
  • Or is there a completely different (hopefully simpler) way?
  • 3
    "If you are typing A E S you are doing it wrong": cs.berkeley.edu/~daw/teaching/cs261-f12/misc/if.html
    – adric
    Jul 15, 2013 at 12:04
  • 2
    All the below solutions seem to be way above my head. Taking the above comment into consideration, I decided to just store the whole 256bit key as a hex string. The question might still be relevant for someone else though, so I'll leave it in its current form. I don't know how to choose to accept an answer though, but upvotes do their job quite well I think. Jul 18, 2013 at 14:46

3 Answers 3


What you do is the following:

  • Generate a long key (this is just a secure randomly generated amount data, you can use 128 bits)
  • You use this key to encrypt your file with AES (meaning you use it as a password)
  • You encrypt the key itself with AES using your password (which is a bit shorter but easier to remember. Now AES requires this again to be either 128, 192 or 256 bits of length so you need to make your password of that length. Hence you can just use PBKDF2 (or scrypt or bcrypt) to create a fixed-length key from your password. DO NOT STORE THIS.
  • You keep a hash of your hashed password using PBKDF2 (or bcrypt or scrypt). This will allow you to check if the password is correct before trying to decrypt your encrypted key.


hash(hash(password)) --> can be stored
hash(password) --> cannot be stored

You always need to provide a salt even if you only have one key (this largely prevents rainbow table lookups). Fortunately for you, salt generation is done automatically by PBKDF2.

So in the end you actually have 3 things:

  • Your encrypted files
  • Your encrypted key
  • A hash of your password to verify it

You might ask why you need the key: If you would change your password (and you had encrypted all your files with your password), you would need to first decrypt all your files with your orignal password and then re-encrypt them with your new password. With this implementation all you need to do is decrypt and re-encrypt the key (as this key serves as your password).


I kind of misinterpreted your question, I've added the key derivation function.

Also a good read (courtesy of IBM)

  • @LucasKauffman +1 for the salt, horray for salt! Isn't salt when used in the context of a reversible algorithm called an initialization vector? That's how I have understood it, same thing different name. Jul 12, 2013 at 17:41
  • 1
    @PsudeoReality the IV is different from the salt actually Jul 12, 2013 at 18:05
  • 1
    The second hash should not be a password-hash but some fast hash like SHA-2. Otherwise you are wasting time on the verification that an attacker can mostly ignore (they can e.g. decrypt the last block and check padding). This time would be better spent on more iterations for the first hash.
    – otus
    Apr 4, 2016 at 7:04
  • 2
    The IBM link looks to be dead; is there a google-able title? Oct 30, 2018 at 14:04
  • 1
    @dtech: You still don't seem to understand. bcrypt/scrypt already do that, as part of their algorithm. The purpose of hash(hash(password)) above is not to increase complexity, it's to give the developer some way of verifying that the password is correct. hash(password) is the encryption key, which cannot be stored, but most encryption algorithms do not provide any way of verifying that the key you're using to decrypt is the correct one. Thus you store hash(key) = hash(hash(password)) for that purpose. It does not affect brute-forcing at all. Dec 15, 2018 at 19:59

To convert a password to an AES key, PBKDF2 is the simplest way of handling it. Just make the sure the password has sufficient entropy.

You do need to use a salt, because it's there to protect against rainbow table attacks.

Depending on your platform, there may already be libraries available to help with this. If not, I'd recommend something close to Lucus Kaufman's solution.


  1. Generate a random 128-bit key (k1), a random 128-bit IV, and a random salt (64 bits is probably sufficient).
  2. Use PBKDF2 to generate a 256-bit key from your password and the salt, then split that into two 128-bit keys (k2, k3).
    • Make sure your algorithm's native output is at least 256 bits, or this will be slow. PBKDF2-SHA256 is a good choice. Don't use two seperate algorithms for this, since it will just make it slower and more complicated for you, but won't slow an attacker down.
    • If your password already has sufficiently high entropy, then you can afford to use a fairly low number of iterations. 1000 iterations will be so fast you won't even notice it (especially since you'll only need to decrypt the key when the program starts up), so there's not much reason to go below that. If your password is weaker, you can turn up the number of iterations to compensate.
    • I don't recommend using bcrypt for this, since it's output is the wrong size and you would need to hash it again, which adds unnecessary complexity.
    • I think scrypt can generate arbitrary-sized output, so it would be a good choice if it's available (this may not be allowed if you want FIPS compliance).
  3. Use k2 to AES encrypt k1 using the random IV.
  4. Save the encrypted key, k3, the salt and the IV to a file somewhere.

Encryption / Decryption:

  1. Use PBKDF2 + your password and the salt from the file to regenerate k2 and k3.
  2. Verify k3. If it doesn't match, either your password is wrong, or someone tampered with your file. Stop here.
  3. Use k2 and the IV from the file to decrypt k1.
  4. Use k1 to encrypt or decrypt files.

Password Change

  1. Decrypt k1 as in the Encryption / Decryption section.
  2. Follow the steps in Setup, using the same k1, but regenerate everything else (new random salt and IV, generate k2 and k3 from the new password).

Do not store k2 anywhere. Do not store k1 unencrypted. Doing either of those things will break the security of your system.

If you don't care about being able to change your password (I would consider this a very important feature, but maybe you don't), then you could skip the steps involving k1, and use k2 as your AES key and k3 to verify it.

You may also find it useful to generate another key for HMAC, so you can verify that the encrypted files haven't been tampered with. If you want to do that, you can generate a 128-bit HMAC key, and encrypt and store that with the main AES key.

  • The password is not entered from outside of the webapp but just stored in the configuration. So I don't think I need to check if the password is correct. Jul 18, 2013 at 20:48

If you generate a key you should somehow hash it, considering that a hash function is "sort-of" like a pseudo-rng. So using PBKDF2 is always good, since it is a key derivation method and is used specifically for this purpose. You pass in a password, and it generates a key you can use based on your password and a salt. As far as Salt, it is automagically part of PBKDF2 so you shouldn't have to worry about it.

If you use something like .NET and store the key in your web.config file you can encrypt parts of your web.config with either the machine key or an RSA key http://msdn.microsoft.com/en-us/library/dtkwfdky%28v=vs.100%29.aspx , the nice thing about this is that windows will take care of storing the RSA key and or machine key. You can even automate this process with your build server.

  • 2
    You would need to re-hash the key you derived with PBKFD2. Otherwise you store the decryption key directly with your encrypted files. Jul 12, 2013 at 12:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .