I have a requirement to store at-rest, symmetrically encrypted customer data in a database. What's the latest recommended way to do this? My research has led me to this:

  1. Generate 8 random bytes for a salt
  2. Generate PBKDF2-HMAC-SHA1 using OpenSSL with the salt from step #1, customer password, 2^16 iterations, and a key size of 32
  3. Encrypt the data with AES-256-CBC using OpenSSL using key from #2
  4. Create an HMAC/SHA1 digest using OpenSSL of the encrypted data from step #3 and the key from #2
  5. Store the encrypted data and the digest in the database either as two separate fields or a single blob with the two items concatenated together by a delimiter
  6. Execute the above in reverse to decrypt
  • Can you please clarify what you are looking to accomplish? Are you only storing passwords? Other data? Must the encryption be reversible? Why do you need steps 4 and 5? Jan 16, 2016 at 18:28
  • @NeilSmithline For example, storing a customer's diary entry, but the data may be anything sensitive, such as pictures, etc. The encryption must be reversible only with the user's interaction by entering the user's password. I'm not sure if steps #4 and #5 are needed, but it is my understanding that digests are useful to ensure no tampering during transmission. It may be possible that the data is never decrypted on my application's server, but rather is sent to the user's browser and decrypted with JavaScript.
    – Kevin
    Jan 16, 2016 at 18:33

1 Answer 1


What you are proposing sounds reasonable.

The salt is on the small side of sufficient but still adequate. Increasing it to 12 or 16 bytes wouldn't likely hurt (salt length isn't closely related to performance) and may make the system a bit more secure.

As far as number of iterations, the advice is as many as you can tolerate. So increase the number of iterations until performance becomes a problem.

A key size of 32 sounds great.

It is unclear to me if you need the digest created in steps 4 and 5. Your comment mentions a concern about tampering during transmission, but if you are using SSL (and if you're not then you basically have no security), the transmission should be secure. So I don't really see a need for it. Especially if you are storing and transmitting the encrypted data and digest together. Perhaps if you stored the digest on a separate site, it could help prove that there wasn't tampering (intentional or otherwise). But I don't see it helping in your situation.

While you probably just didn't bother to mention that you are saving the salt in your question, I'll mention that you must save it so that you can recreate the 32-byte encryption key for decryption.

Generally, this sounds reasonable.

  • Old question but, shouldn't it be a problem that he's using the same key for both encryption and hmac? Feb 7, 2018 at 13:06

You must log in to answer this question.

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