Jae Bin
Jae Bin

Reputation: 49

Storing Passwords on MySQL database: Hash vs Encryption?

I've been reading the pros and cons of using hash vs encryption when storing sensitive data on a MySQL database, and the arguments from both sides by people who favor either hash or encryption have only left me in confusion and uncertainty on which one to use.

Hash:

"INSERT INTO users (`id`,`username`,`password`) VALUES("Bob",SHA2("password1234"));"

CONS:

Encryption:

"INSERT INTO users (`id`, `username`, `password`) VALUES ("Bob", aes_encrypt("password1234", "key1234"))";

CONS:

So which is really more ideal in terms of providing security and performance (fast read and retrieval from database)? (In a table of approx 1,000 - 5,000 rows).

Upvotes: 1

Views: 12047

Answers (1)

mjuarez
mjuarez

Reputation: 16834

I'm going to go ahead and say neither of them. You should never store a password, even encrypted. That makes you vulnerable to password stealing, either external or internal to your organization. Also, SHA2 is not deprecated per-se, and you don't specify the hash length. SHA2-512 or even SHA2-256 are still considered excellent cryptographic hashes. You could also use the more recent SHA3/Keccak crytographic hash, but from recent literature, it's not better than SHA2 as much as different. Both are still endorsed by NIST.

However, there's consensus in InfoSec that a simple crypto hash is not enough for properly storing secrets. As of 2018, it seems either PBKDF2, bcrypt or ARGON2 are widely considered the top contenders for "best" crypto hash algorithms. You can read a much more detailed explanation about passwords and cryptographic hashes on this Security StackExchange link https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords/31846#31846

The link above doesn't explain ARGON2, which was the recent winner of the Password Hashing Competition. You can read more about it here: https://github.com/p-h-c/phc-winner-argon2

My recommendation would be to:

  • Add a fourth field to the table called salt. This should be a truly random 8+ digit alphanumeric string, stored in plaintext.
  • Store the "password" as CryptoHash(salt + 'password1234'). This protects you from rainbow tables, since it's not feasible to precalculate ALL rainbow tables for all possible salts.

Replace CryptoHash above with either PBKDF2, bcrypt or ARGON2, and you'll have a pretty good password storage mechanism.

Upvotes: 8

Related Questions