I'm using BCrypt to hash my passwords on the server side. Before I store it in my MySQL database, would it be overkill to encrypt my hashed-BCrypt password or would storing the hash directly in the database suffice?

This website advises to encrypt passwords after hashing them:

As long as an attacker can use a hash to check whether a password guess is right or wrong, they can run a dictionary or brute-force attack on the hash. The next step is to add a secret key to the hash so that only someone who knows the key can use the hash to validate a password. This can be accomplished two ways. Either the hash can be encrypted using a cipher like AES, or the secret key can be included in the hash using a keyed hash algorithm like HMAC.

I'm coding in Java. I'm trying to gauge whether the added layer of protection vs. speed performance of read & retrieval of passwords for user logins is worth it or not.

  • 1
    "salting" (and use correct hashing algorithm) is the essential good practice you should implement in priority. – Pac0 Oct 13 '18 at 8:21
  • bcrypt is already salted by design. – Royce Williams Oct 14 '18 at 8:02
  • Applying two functions seems slower than simply salting. And they should be equally secure. – Rick James Oct 19 '18 at 2:47

Adding such an additional secret - and, ideally, storing it securely in an HSM - is indeed a normal practice. It's not common, exactly; many platforms are using hashes alone (and often poorer hashes than bcrypt). But an additional layer definitely makes things harder for the attacker - if done right.

Some further advice: roll as little of the implementation yourself as possible. Instead, find well-established libraries to do as much of the crypto as you can (because it's hard to get right - and getting it wrong can be very bad indeed).

Note that bcrypt has some limitations - notably that the maximum plaintext length allows is 72 bytes. It also is not memory-hard, and therefore is subject to attack with (relatively) lower-cost specialized hardware with many cores in parallel. The modern options - scrypt and the Argon2 family - are resistant to low-memory parallelization. Look for well-baked implementations of those. Also, use bcrypt with as high of a work-factor cost as your users (and projected hardware) can tolerate (cost 12 is often where it starts to get close to the break-even point, but YMMV; test on your hardware).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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