MD5,密码散列和盐位置
在我开始之前,我知道MD5已经被攻破(碰撞攻击和散列速度),不应该用来散列密码,但只是为了它,忍受着我。
我的问题是:当用md5散列时,盐的位置如何影响散列的“质量”或“强度”?
假设我有以下一段代码,它使用他的电子邮件地址的一部分作为盐散列用户密码:
<?php
$email = 'user@emailservice.ex';
$password = 'RandomPassWithChars';
$segments = explode('@', $email);
list($saltPart1, $saltPart2, $saltPart3) = $segments;
$hash = md5($saltPart1.$password.$saltPart3.$saltPart2);
?>
这段代码是否会减缓蛮力/字典/彩虹桌的攻击,比说:
<?php
$password = 'RandomPass';
$salt = 'RandomSaltStoredInTheDatabase';
$hash = md5($password, $salt);
?>
是否值得尝试在第一个代码中使用密码,或者与第二个代码的结果相同? 这有什么好处吗? 第一个代码延迟破解密码列表的方式比第二种方式散列吗?
这导致我有第二个问题:它是否安全地将salt存储在数据库中,而不是从用户id(例如电子邮件地址)获取salt? 我看到它的方式,一旦攻击者获得了一个数据库的副本,它也使得他的生活变得轻而易举,试图破解这些哈希值。 但是如果盐没有储存,攻击者也需要创建盐的算法。 如果我错了,请纠正我。
我希望我让自己清楚。 提前感谢任何答案。
第一个问题:
盐的位置对特定散列的安全性没有影响。 一个好的散列函数具有完美的熵,因为对于每一个改变的输入位,每个输出位有50%的改变机会。
特定顺序的任何可能的安全优势完全取决于用于将盐与预期密码连接的算法的相对缓慢(例如,如果"password" . "salt"
比"salt" . "password"
慢, "salt" . "password"
前任的)。 但是,大多数编程语言没有这种性能“问题”。
第二个问题:
如果盐被明确地存储在数据库中,攻击者将知道盐,并且能够发起蛮力哈希攻击。 如果盐是未知的,仍然可以使用强力密码攻击(尽管通过在尝试之间插入延迟可以使其变得无效)。 此外,攻击者可能能够逆向工程程序并检索散列字段。
至于哈希的安全性,如果用户在两个不同的地方有相同的电子邮件和密码,这就否定了随机盐的好处之一,因为相同的哈希将在两个地方可见。
就个人而言,我认为散列的最佳方法是使用:
"password" . "salt" . "internalconstantvalue"
这具有简单的优点,并且与其他大多数安全方法相比,其安全性更低。
这取决于攻击者是否试图绕过你的安全或者他是否试图找到密码。
如果攻击者依赖于哈希算法的密码弱点发现与数据库的给定散列发生冲突,则盐不会产生任何影响:我有一堆数据,我想找到一些输入XXX哈希算法,它给了我输出中相同的一堆比特。
如果他试图通过尝试每种可能的组合来暴力破解密码,那么他可以收集的原始密码信息将有助于:
通过创建自己的salt算法,您实际上正在尝试通过模糊处理来实现安全性,这确实会限制任何不知道算法的人使用密码强制,但不会加强散列算法。
当您处理密码安全性时,请始终假设攻击者能够访问您的数据库,然后他可以访问您的代码。
因此,当涉及到mcirotime()
时,只需生成随机值的散列(例如mcirotime()
),并在散列之前使用它来限制密码,并将其存储在密码旁边列中的数据库中。
当将密码添加到密码中时,我个人的观点是,如果你把它放在第一个或最后一个或中间,它并不重要。
你想要安全吗? 然后使用慢哈希算法,我强烈推荐PHPass,因为它使用bcrypt
(基于Blowfish)作为默认哈希算法。