在 MySQL 数据库上存储密码:哈希与加密?

Storing Passwords on MySQL database: Hash vs Encryption?

我一直在阅读在 MySQL 数据库上存储敏感数据时使用散列与加密的优缺点,双方支持散列或加密的人的论点只剩下我了困惑和不确定使用哪一个。

哈希:

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

缺点:

加密:

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

缺点:

那么,就提供安全性和性能(从数据库快速读取和检索)而言,哪个更理想? (在 table 中,大约 1,000 - 5,000 行)。

我先不说了。您应该永远不要 存储密码,即使是加密的。这使您容易受到组织外部或内部的密码窃取。此外,SHA2 本身并没有被弃用,并且您没有指定哈希长度。 SHA2-512 甚至 SHA2-256 仍然被认为是优秀的加密哈希。您也可以使用更新的 SHA3/Keccak 密码哈希,但从最近的文献来看,它并不比 SHA2 好多少,而是有很大的不同。两者仍然得到 NIST 的认可。

但是,InfoSec 一致认为简单的加密散列不足以正确存储秘密。截至 2018 年,似乎 PBKDF2、bcrypt 或 ARGON2 被广泛认为是 "best" 加密哈希算法的顶级竞争者。您可以在此 Security StackExchange link 上阅读有关密码和加密哈希的更详细说明 https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords/31846#31846

上面的 link 没有解释 ARGON2,它是最近密码哈希竞赛的获胜者。您可以在这里阅读更多相关信息:https://github.com/p-h-c/phc-winner-argon2

我的建议是:

  • 向名为 salt 的 table 添加第四个字段。这应该是一个真正随机的 8 位以上的字母数字字符串,以明文形式存储。
  • 将 "password" 存储为 CryptoHash(salt + 'password1234')。这可以保护您免受彩虹 tables 的影响,因为预先计算所有可能的盐的所有彩虹 tables 是不可行的。

将上面的 CryptoHash 替换为 PBKDF2、bcrypt 或 ARGON2,您将拥有一个非常好的密码存储机制。