可能重复:
我应该使用哪种密码散列方法?
在堆栈溢出和其他站点上的数据库中有大量关于密码安全性的精彩帖子,由于我对此完全陌生,因此在过去的几天里我花了很多时间试图了解更多关于它的信息。但是,有很多不同的建议和最佳实践,我仍然很困惑......
此外,从 2007 年到 2010 年还有很多较旧的帖子等我看到事情变化的速度有多快,我不确定这是否仍然像他们建议的那样普遍使用。所以,我想总结一下我在帖子中发现的内容,然后询问我发现的这种方法是否是一个好习惯......
所以,这不是一个指南,而是一个总结,我知道这是非常基础的,如果有错误,请纠正我!
- 顺便提一下:您永远不应该存储纯文本密码:)
- 您“单向”散列密码,因此没有人可以看到纯文本。当用户输入密码时,您以相同的方式对其进行哈希处理,并将其与数据库中的哈希密码进行比较。
- 除了散列密码之外,您还应该对其进行加盐。您将盐添加到纯密码字符串并散列新字符串。如果普通密码很弱,添加盐会使其更长更强。
- 盐还应该是随机的(我读过术语“盐”意味着它无论如何都是随机的,否则它被称为“密钥”?)。这是为了防止彩虹表攻击,因为攻击者需要为每个盐创建一个表,这在时间等方面要昂贵得多。此外,如果两个用户具有相同的密码,如果您使用随机盐,您将无法识别它。
- 盐不是秘密!它存储在散列密码旁边的数据库中。但是,使用时间戳、用户的电子邮件地址或与用户相关的任何其他内容作为随机盐可能不是最好的主意。作为一个原因,例如提到用户倾向于在多个站点/服务上使用相同的密码。那么,盐应该是一个随机字符串,我读过最好的应该是 64 位的?
- 下一步是向散列过程添加迭代(1000 或更多循环),因此将盐添加到密码中,然后一遍又一遍地对其进行散列,这意味着用户在登录时只需等待几分之一秒中,但总结一下,如果您的数据库中有大约 10.000 个条目。
- 如果您添加一个站点密钥,这可能会带来一点好处,例如除了盐之外存储为全局变量。但是,您应该始终假设攻击者也可以访问您的文件系统。
- 哈希算法:我发现使用 MD5、SHA1 和其他弱方法肯定不再安全......
那么,对于是否使用 SHA256、SHA512 有不同的看法?你应该使用 hash_hmac 吗?有人说是的:(http://rdist.root.org/2009/10/29/stop-using-unsafe-keyed-hashes-use-hmac/)有人说使用库是唯一安全的方式......然后在一篇文章中我读过一次或两次不要将库用作 bcrypt 或泡泡鱼?
是否真的有必要使用库或者例如这样的方法就足够了:
function hash_password($password, $nonce) {
for ($i = 0; $i < 5000; $i++) {
$hashed_pass = hash_hmac('sha512', $hashed_pass . $nonce . $password, $site_key);
}
return $hashed_pass;
}
很多人说不要发明自己的算法,所以我有点害怕使用任何自己发明的东西。
我可以想象这很难预测,但是今天使用的方法能被认为足够安全多久?
更新:所以,感谢您的所有反馈。正如我看到的和你们中的许多人所说,缺少一个要点:密码安全,这意味着强密码是基本的。我想我收到了消息,再次感谢您!:)
更新 2:为了完成,我在http://www.lateralcode.com/creating-a-random-string-with-php/上找到了以下代码,用于生成随机盐:
function rand_string( $length ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!§$%&/().-:;_#+*[]{}=";
$size = strlen( $chars );
for( $i = 0; $i < $length; $i++ ) {
$str .= $chars[ rand( 0, $size - 1 ) ];
}
return $str;
}
$random_salt= rand_string(20);