我有几个关于密码散列的问题。我发现hash_hmac是一个很好的散列密码函数,但仍然存在一些问题。
从另一个stackoverflow问题有人回答:
return hash_hmac('sha512', $salt . $user['password'], $this->site_key);
我最初的问题是关于hmac如何使用密钥,在维基百科上,hmac函数似乎会在哈希之前将密钥添加到每条消息中,那么密钥本身是否不充当盐呢?然后,我是否可以删除$salt,而只使用用户特定的键?hash_hmac('sha512', $user['password'], $this->user_key)
最大的问题仍然是$salt(或第一个问题中的$user_key)的生成。如果要使用rand()生成用过的盐,我不喜欢将它们存储在数据库中。那么什么是生成用户特定盐的好方法呢?
如果我将将盐存储在数据库中,使用
是否安全?$user_key = $user['salt'] . $this->site_key;
return hash_hmac('sha512', $user['password'], $user_key);
使用随机的每个用户盐,并将其与散列一起存储在数据库中。它是一个在你的配置文件中的每个站点的秘密。这样,攻击者在开始破解密码之前,需要获得数据库和配置文件的访问权限。
要安全地散列密码,我建议结合以下三种成分:
- 一个很好的键衍生函数。它类似于普通的散列,但速度慢,而且要加盐。bcrypt和PBKDF2是常用选择。
- 随机的每个用户盐。这样做的主要目的是,对于每个用户来说都是不同的。将它与散列一起存储在数据库中。如果攻击者得到它,没有问题。
- 每个站点的秘密。这样做的目的是,获得对数据库的访问权限不足以破解密码。攻击者也需要访问配置文件。即使他知道了每个站点的秘密,这个方案仍然是安全的,就好像你没有使用任何秘密一样。
使用bcrypt!
安全存储密码的经典文本:
http://codahale.com/how-to-safely-store-a-password/引自文章:
盐不会帮助你
奖金!
使用bcrypt比欺骗自己的bs和可能不正确的盐化方案更简单。
永远不要实现你自己的密码系统或熵源