在开始之前,我知道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);
?>
是否值得尝试使用第一个代码或者yelds中的密码 与第二个代码相同的结果?这有什么好处吗? 第一个代码是否会延迟破解密码列表 这样做的第二种方式?
这引出了我第二个问题: 是否安全地将盐存储在数据库中而不是获取盐 来自用户ID(比如电子邮件地址)? 我看到它的方式,一旦攻击者获得了数据库的副本 这也使得他的生命变得有点轻松,试图破解哈希。但是如果没有储存盐,攻击者也需要创造盐的算法。如果我错了,请纠正我。
我希望我清楚自己。谢谢你提前得到任何答案。
答案 0 :(得分:8)
第一个问题:
salt的位置对特定哈希的安全性没有影响。良好的散列函数具有完美的熵,因为对于每个输入位的变化,每个输出位有50%的可能性发生变化。
某个订单的任何可能的安全性好处完全取决于用于将盐与预期密码连接的算法的相对缓慢(例如,如果"password" . "salt"
慢于"salt" . "password"
,则使用前者)。但是,大多数编程语言都没有那种性能问题。
第二个问题:
如果salt明确存储在数据库中,攻击者将知道salt,并能够发起暴力哈希攻击。如果盐是未知的,仍然可以使用暴力密码攻击(尽管通过在尝试之间插入延迟很容易使其无效)。此外,攻击者可能能够对程序进行反向工程并检索哈希字段。
至于哈希的安全性,如果用户在两个不同的地方有相同的电子邮件和密码,这就否定了随机盐的一个好处,因为两个地方都可以看到相同的哈希值。
就个人而言,我认为散列的最佳方法是使用:
"password" . "salt" . "internalconstantvalue"
这样做的好处是简单,并且不比大多数其他安全方法安全。
答案 1 :(得分:1)
这取决于攻击者是否试图绕过您的安全性,或者他是否试图找到密码。
如果由于哈希算法的加密弱点,攻击者依赖于使用数据库的给定哈希值找到 collision ,那么salt将没有任何影响:我有一堆位和我想找到一些XXX散列算法的输入,它给出了输出中相同的一堆位。
如果他试图通过尝试每种可能的组合来强制密码,那么他可以在原始密码上收集的任何信息都会有所帮助:
通过创建自己的salt算法,您实际上是在尝试通过混淆来实现安全性,这确实会限制任何不了解您的算法的人强制使用密码,但它不会强化哈希算法。
答案 2 :(得分:0)
当您使用密码安全性时,请始终假设如果攻击者可以访问您的数据库,那么他就可以访问您的代码。
因此,当涉及到salting时,只需生成随机值的哈希值(例如,mcirotime()
)并在散列之前使用它来密码密码并将其存储在密码旁边的列中的数据库中。
当谈到将密码添加到密码时,我的个人意见是,如果你把它放在第一个或最后一个或中间并不重要。
你想要安全吗?然后使用慢哈希算法,我强烈推荐使用PHPass,因为它使用bcrypt
(基于Blowfish)作为默认的哈希算法。