【发布时间】:2010-01-11 18:29:56
【问题描述】:
我将为我的网站使用 sha256,以保护我的用户密码,并且作为盐,我正在考虑使用用户 ID(int auto_increment)。这将是独一无二的,但不是很长和很难,并且是公开的(user.php?id=1),但它是否唯一很重要?
hash('sha256', $id . $password);
【问题讨论】:
我将为我的网站使用 sha256,以保护我的用户密码,并且作为盐,我正在考虑使用用户 ID(int auto_increment)。这将是独一无二的,但不是很长和很难,并且是公开的(user.php?id=1),但它是否唯一很重要?
hash('sha256', $id . $password);
【问题讨论】:
是的,盐的唯一性很重要(碰撞不太可能发生),但它也应该有足够的熵(随机且足够长)。用户 ID 不是随机的,可能太短,所以最好的办法是使用随机生成的字符串并将它们与哈希一起存储在数据库中。
假设 UID 9 的用户选择了一个愚蠢的密码:password。然后,将被散列的结果字符串可能是9password。您可以想象,即使在这种情况下,完整的字符串也可能出现在rainbow tables(包含大量哈希及其原始字符串的表)中。
如果这种情况下的盐是OTAzMzYzODQzMjk5NTM1NDc1N,则要散列的字符串是OTAzMzYzODQzMjk5NTM1NDc1Npassword,它不太可能出现在彩虹表中。此外,输入字符串更长,降低了暴力攻击的风险。
【讨论】:
这可行,但使用盐的目的是区分散列密钥以加强加密算法。使用唯一的、随机生成的/时间加盐字符串作为盐会更好。另外最好不要在同一个表中包含盐和哈希键。
【讨论】:
你的盐应该不容易猜到。在其中一种更基本的形式中,您可以简单地使用基于当前 TIMESTAMP 的盐创建一个盐
date('U')
由于其长度、唯一性以及您将其存储在数据库中并且不公开提供这一事实,它更加安全。然后你会以这样的方式使用它:
$hash = date('U');
$pass = hash('sha256', $hash . $password);
以及在登录时检查密码:
// return query object based on matching email/username
if ($userobj->pass === hash('sha256', $userobj->salt .$_POST['pass'])) {
// correct pass
}
【讨论】:
我认为这不是一个好的选择:我会使用更随机的盐将其保存到用户记录中。 也许在密码字段中保存这个字符串: sha256($password . $randomSalt) 。 '$' 。 $随机盐
这样你就可以在登录时检索盐来检查密码。
(无论如何你也可以单独使用另一个字段作为盐)
【讨论】: