为什么不使用MD5进行密码散列?

Mas*_*oud 3 security passwords hash md5 password-storage

我有一个白帽子黑客的朋友.他说md5并不是那么糟糕,实际上它确实非常安全,只要我们正确使用它.

我相信他是对的.据我所知,有三种方法可以打破哈希:

  1. 使用彩虹桌(可以用长/随机盐保护)
  2. 碰撞(可通过多种盐或哈希来防止 - 如下例所示)
  3. 生成时间(如果我们为每个用户使用足够长的盐值,那么这一点并不重要 - AFAIK)

我和我的朋友认为Blowfish并不是真的有需要,也可能是有害的,因为它可以减慢密码验证过程,并且它可以与DDOS攻击一起使用,即使使用较少的资源,也可以分解服务器.

所以,我想确保遵循算法真的安全吗?并且,是否有真正的理由选择Blowfish哈希算法?

// return a 256 bit salt + 128 bit md5 binary hash value
function hash(password, salt=null)
{
    salt = (salt != null) ? salt : Random256BitBinaryValueGenerator();
    // What about using another user-specified parameter, like email address as salt?

    return salt + md5(salt + password) + md5(password + salt);

    // Or just use a non-cryptographic hash algorithm like crc32 to prevent collisions:
    // return salt + md5(salt + password) + crc32(salt + password);

    // Or even use two different salts:
    // return salt + md5(salt + password) + md5('C' + salt + password);
}

// check password
function check(password, hash_value)
{
    return hash(password, substring(hash_value, 0, 32)) == hash_value;
}
Run Code Online (Sandbox Code Playgroud)

Sil*_*Fox 15

碰撞阻力 MD5的财产已被打破很长一段时间.请注意,preimage抵抗和第二前像像抗性尚未被破解,但是因为有更好的算法(SHA-2),移动到这些算法是明智的,而不是依赖已经开始失去其的加密哈希加密属性.注意:当存储散列密码时,碰撞阻力属性无关紧要 - 您需要确保的是前映像电阻属性是合理的 - 在给定特定散列值(和盐)的情况下找到原始密码在计算上是不可行的.正如我所提到的,由于其中一个加密属性已被破坏,我担心其他人将很快跟进.

当您存储密码哈希时,您应该建立一些保护,以便在攻击者设法提取这些哈希值时无法检索原始密码.这很重要,因为如果攻击者设法只检索密码表,那么他们就可以使用这些数据直接登录到您的系统,或者登录到用户重复使用相同密码的其他系统.

存储密码时,使用慢速算法很重要,例如bcrypt,scrypt或pbkdf2.合法用户在首次登录时只需要经历一次延迟.攻击者必须经历他们猜测的每个密码的延迟 - 记住彩虹表将不会在这里使用,因为密码被腌制.攻击者将根据您选择的算法和迭代计数对每个密码猜测进行散列.

调整系统的迭代次数非常重要,因此使用正确的"强度"不会导致合法用户在登录系统时出现任何真正的烦恼.这被称为"轮次"数或"迭代次数".例如,迭代大约一秒应该就足够了.可以安全地假设攻击者可以以系统硬件速度的十倍速度运行哈希值.因此,这限制了攻击者每秒10次猜测,而不是MD5的20亿次.

关于DoS攻击

是的,您的应用程序在登录时执行的额外处理可能是攻击者向您的应用程序提交真正长密码的目标,或者是为了消耗服务器上的CPU和内存资源而反复使用登录请求命中它.你是对的.

可以通过以下方式减轻这些类型的攻击:

  • 记录每次登录尝试的用户名和IP地址.在说出6次尝试失败后,如果再次重复该用户名或IP,则会引起应用程序的响应延迟.这也有助于缓解一般的密码猜测攻击.
    • 例如,你可以人为地延迟1秒,然后是2秒,然后是4,直到合理的值(例如16秒).
    • 这样做的好处是,攻击者无法故意锁定另一个帐户,因为合法用户只需要等待16秒.
    • 攻击者可以使用僵尸网络和随机用户名来绕过这些检查,但是如果没有这种控制,他们将需要大量的IP地址,而更随意的攻击者也不会意识到响应的延迟是人为的.
  • 监控系统上的登录尝试次数.一旦超过设定的阈值速率(例如每秒10次),引入CAPTCHA以解决继续登录过程.您选择的阈值速率在很大程度上取决于系统的用户群和容量.
  • 实施双因素身份验证.只有在验证一次性密码后才能通过散列验证密码.


mar*_*kli 5

MD5的问题正是如此之快,您可以使用通用硬件计算大约9 Giga MD5/s.要用大约200000个单词来强制整个英语词典,你只需要几分之一毫秒.

这就是像BCrypt这样的适当哈希算法提供成本因素的原因.成本因子定义了计算哈希所需的时间,并且可以在将来添加.登录50毫秒几乎不是障碍,但对于暴力破解它是致命的.

  • @Masoud - 一个很好的问题.•不,它不会成为下一个MD5,因为成本因素,将此因子增加1将使计算哈希的必要时间加倍.•不,您可以鼓励用户使用更强的密码,但您不能强制使用它们.复杂的密码规则将与良好的密码方案冲突,用户对密码非常有创造性:`Password-2015`将满足大多数规则,但密码非常弱.即使弱密码也应尽可能保护,即使不建议使用. (2认同)