TL;DR: Is encrypting data with AES CBC with random IV + PBKDF2 key using the username as salt safe?

I have searched the internet, but I could not find a proper answer that encompasses the "AES CBC and random IV with PBKDF2 same salt" dilemma.

The scenario
I am developing a client/server/DB system, and my users need to have their data encrypted and accessible from multiple devices.

  1. Users log in with a username and password. The username and password hash (bcrypt) are saved to the database.
  2. Users create a series of items (user content) on their devices.
  3. Each item the user creates is encrypted with AES CBC and gets its random IV. Every item will use the same key generated via PBKDF2 with 310.000 iterations using the username as salt.
  4. Encrypted content is saved into the database along with IV (the key is not sent to DB, of course).
  5. Users can log in to another device and get content downloaded and decrypted using a (reverse) process as described in step 3.

Maybe it is relevant to understand that users will not share data. It is individual.

Why not different salts and, therefore, different keys?
I have tried using different salts and storing the salts along IV and the encrypted item, but using different salt in PBKDF2 for every item the user creates is painfully slow (given the 310k iterations). It is slow, mainly when the user downloads his 100s of items from DB. It was unacceptable.


1 Answer 1


The point of salting is to prevent an attacker preparing a rainbow table - that is, for every interesting password, calculate the hash, and then look to see if any of the password hashes match.

For an application which has multiple installations, there may be some usernames ("admin", "root", "jsmith") which get reused. For a very widely distributed application, it might be worthwhile constructing the rainbow table. If you can add some value into the salt which is unique per installation (e.g. some random value created at installation time), that should defeat that. Alternatively, you may decide the risk is low enough not to worry about.

I am not a cryptographer, I only play one on the internet. One of the rules I use for keeping out of trouble is "never reuse keys". However, you don't need to rerun PBKDF2 again for each object - you calculate that once, and then just feed the output of that + some value which is unique for each file into a key derivation function like HKDF, and use that to encrypt the file. Alternatively, a real cryptographer may be along shortly to say "nah, using the same key is fine".

I would not reuse the IV as your unique value for differentiating the key (without reassurance from a cryptographer), but it certainly should be safe to generate a random value, and then use HKDF on that to generate one value which is used as the IV, and another value which is used to differentiate the key (then store the root random value in the database).

  • $\begingroup$ Thanks for your comments! I like the idea to add randomness to the salt. In my case IVs are unique as well; every item gets its own IV. The problem with generating a key for every item is that when the items are downloaded (think of 100s), to decrypt them, I need to regenerate 100s of keys (remember, every item was encrypted with a different key). With PBKDF2 on 310k iterations, those 100s items take 10+ seconds to be decrypted (this is too much for our users). What takes the bulk of 10 seconds is the PBKDF2 being run to find the individual key of every single item. $\endgroup$ Commented May 18, 2023 at 16:53
  • $\begingroup$ Yes. So don't run PBKDF2 hundreds of times. Run it once and then generate the actual decryption keys by running HKDF hundreds of times - that should take something less than a millisecond. $\endgroup$ Commented May 18, 2023 at 16:59
  • $\begingroup$ I have implemented PBKDF2 and then HKDF. $\endgroup$ Commented May 22, 2023 at 15:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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