我有一个朋友,他是白帽黑客。他说 md5 并没有那么糟糕,而且实际上非常安全,只要我们正确使用它。
我相信他是对的。据我所知,有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;
}
The 抗碰撞性MD5的属性早已被破坏。请注意,原像抵抗第二个原像抵抗尚未被破解,但是由于存在更好的算法(SHA-2),明智的做法是转向这些算法,而不是依赖已经开始失去其加密属性的加密哈希。注:抗碰撞性能不要紧当存储散列密码时 - 您需要确保原像抵抗属性是健全的 - 在给定特定散列值(和盐)的情况下,在计算上无法找到原始密码。正如我所提到的,由于其中一个加密属性已经被破坏,我担心其他加密属性很快也会被破坏。
当您存储密码哈希值时,您应该构建一些保护措施,以便在攻击者设法提取这些哈希值的情况下无法检索原始密码。这很重要,因为如果攻击者设法检索密码表,他们就可以使用这些数据直接登录您的系统,或者登录用户重复使用相同密码的其他系统。
存储密码时,重要的是使用slow算法,例如 bcrypt、scrypt 或 pbkdf2。合法用户在首次登录时只需经历一次延迟。攻击者将不得不经历他们猜测的每个密码的延迟 - 请记住这里不会使用彩虹表,因为密码是加盐的。攻击者将根据您选择的算法和迭代计数对每个密码猜测进行哈希处理。
调整系统的迭代次数非常重要,这样使用正确的“强度”就不会在登录系统时给合法用户带来任何真正的烦恼。这称为“轮数”或“迭代计数”。例如,迭代大约一秒就足够了。可以安全地假设攻击者可以以系统硬件速度十倍的速度运行哈希值。因此,这将攻击者限制为每秒 10 次猜测,而不是 MD5 的每秒 20 亿次。
关于 DoS 攻击
是的,您的应用程序在登录之前执行的额外处理可能会成为攻击者的目标,攻击者可以向您的应用程序提交非常长的密码,或者通过登录请求重复点击它,以消耗服务器上的 CPU 和内存资源。你的担心是对的.
可以通过以下方式缓解此类攻击:
- Log the username and IP address of each login attempt. After say 6 failed attempts, introduce a delay in response from your application if that username or IP is repeated again. This will also help mitigate password guessing attacks in general.
- 例如,您可以人为地延迟 1 秒,然后 2 秒,然后 4 秒,直至合理的值(例如 16 秒)。
- 这样做的优点是攻击者无法故意锁定另一个帐户,因为合法用户只需等待 16 秒。
- 攻击者可以使用僵尸网络和随机用户名来绕过这些检查,但是与没有这种控制的情况相比,他们需要大量的 IP 地址,而且更随意的攻击者也不会意识到响应延迟是人为的。
- 监控系统上的登录尝试次数。一旦超过设定的阈值速率(例如每秒 10 次),请引入验证码来解决以继续登录过程。您选择的阈值速率很大程度上取决于系统的用户群和容量。
- 实施两因素身份验证。仅在验证一次性密码后才继续通过散列来验证密码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)