【发布时间】:2008-12-03 00:17:24
【问题描述】:
我的 mysql 数据库中有一个包含密码列的用户表。目前,我使用 MD5 算法对用户密码进行哈希处理以存储在数据库中。现在我喜欢认为我是一个有安全意识的人。我在阅读 MySQL 文档时注意到他们不推荐 MD5 或 SHA/SHA1 散列方法,但不提供替代方法。
在 MySQL 中散列密码的最佳方法是什么?在我当前的实现中,PHP 和 MySQL 原生支持的函数将是理想且必要的。
谢谢!
【问题讨论】:
我的 mysql 数据库中有一个包含密码列的用户表。目前,我使用 MD5 算法对用户密码进行哈希处理以存储在数据库中。现在我喜欢认为我是一个有安全意识的人。我在阅读 MySQL 文档时注意到他们不推荐 MD5 或 SHA/SHA1 散列方法,但不提供替代方法。
在 MySQL 中散列密码的最佳方法是什么?在我当前的实现中,PHP 和 MySQL 原生支持的函数将是理想且必要的。
谢谢!
【问题讨论】:
不一定你不应该使用 MD5,而是你不应该使用只是 MD5,因为这会使你容易受到彩虹表攻击(彩虹表就是一个表预先计算的哈希值——如果你的密码很普通或很简单,攻击者只需查找哈希值,他就知道你的明文密码。)
至少你应该为每个密码添加一个盐,这样任何现有的彩虹表都无用,迫使攻击者为你的密码数据库生成一个全新的彩虹表。
更好的办法是为您的数据库中的每个密码使用不同的盐,比如与之关联的用户名,这样攻击者甚至无法为您的整个数据库生成彩虹表,并且必须单独破解每个条目。
MD5 也是一种非常快速的算法。速度是破解的敌人——生成哈希所需的时间越长,黑客每次尝试所需的时间就越长。对于登录到您的网站的用户来说,像每次使用新的额外盐对纯文本进行 100 次散列处理这样简单的操作几乎无法察觉(如果有的话),但它会增加暴力破解密码所需的时间。 100 次。
这里有更多详细信息:http://www.codinghorror.com/blog/archives/000953.html
【讨论】:
按照今天的标准,MD5 被认为是弱的。破解使用 MD5 生成的哈希仍然需要一些工作,但它比通过暴力猜测密码要容易几倍。理想情况下,破解哈希不应该比暴力破解更容易。
SHA1 也被认为比暴力猜测密码更容易破解。
我实际上为 MySQL 贡献了一个补丁,以显示来自 OpenSSL 的 SHA224、SHA256、SHA384 和 SHA512 函数。 NIST 推荐这些用于密码散列(实际上是 SHA256 和更高版本)。
我的补丁是由 MySQL 工程师完成的,如果我记得的话,它包含在 MySQL 6.0.5 及更高版本中。
如果您使用较早版本的 MySQL(而谁没有使用),那么您可能可以在您的宿主语言中使用强散列函数的实现。例如,PHP 有 hash() 函数。您可以在您的应用程序中进行哈希处理并将生成的消息字符串保存到数据库中。
也别忘了salting!
【讨论】:
这个问题是 7 岁。在那段时间里,我们在计算方面取得了进步,MD5 和 SHA1 现在很容易被现代计算机破解。现在应该避免这些。
PHP 5.5 引入了password_hash,它使用了更安全的 bcrypt 算法。虽然 MySQL 可以加密/解密 bcrypt,但这是一个糟糕的解决方案,因为您不仅会给数据库层增加潜在的大计算负载,而且the unhashed password could be stored in your logs
在任何情况下,明文密码都不应该命中 MySQL,即使是在查询级别。否则,您可能会将密码写入日志(查询日志、一般日志、慢查询日志等)。这太可怕了。所以不,甚至不要打扰......
【讨论】:
MD5 和 SHA-1 可能不再推荐,因为 know attacks。但是,对于大多数用例,它们仍然通常足够了。
如果您正在寻找更多选项,只需使用 PHP 的 hash functions -- 您已经在此处找到了 plenty of options。
【讨论】:
我正在使用组合。例如 SHA1(MD5()) 工作正常。
【讨论】:
SHA1(MD5( 的安全性低于SHA1()
myHash 函数只有两个可能的结果;)