Mysql – Is it overkill to encrypt an already hashed BCrypt password

encryptionjavaMySQLpasswordSecurity

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.

Best Answer

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).