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? – Neil Smithline Jan 16 '16 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 '16 at 18:33
up vote 0 down vote accepted

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? – user1777914 Feb 7 at 13:06

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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