为什么不使用MD5进行密码散列?
我有一位朋友是白帽黑客。 他说md5并不是真的那么糟糕,而且确实很安全,只要我们正确使用它。
我相信他是对的。 据我所知,有三种方法可以打破哈希:
我和我的朋友相信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;
}
MD5的抗碰撞性能已经被打破了很长一段时间。 请注意,原像阻抗和第二原像阻力尚未破解,但由于有更好的算法(SHA-2),转移到这些算法是明智的,而不是依赖于已经开始丢失其加密哈希的算法密码属性。 注意:存储哈希密码时,碰撞抵抗属性并不重要 - 您需要确保的是,图像抗阻性是健全的 - 在给定某个哈希值(和盐)的情况下找到原始密码在计算上是不可行的。 正如我所提到的那样,由于其中一个加密属性已经被破坏,我会担心其他人会很快跟进。
当您存储密码散列时,您应该构建一些保护措施,以便在攻击者设法提取这些散列时,无法检索原始密码。 这一点很重要,因为如果攻击者设法检索密码表,则他们可以使用这些数据直接登录到系统,或者登录到其他用户重新使用相同密码的系统。
存储密码时,使用慢速算法很重要,例如bcrypt,scrypt或pbkdf2。 首次登录时,合法用户只需要经历一次延迟。 攻击者必须经历他们猜测的每个密码的延迟 - 记住彩虹表不会在这里被使用,因为密码是盐渍的。 攻击者会根据您选择的算法和迭代次数散列每个密码猜测。
调整系统的迭代次数非常重要,因此在登录系统时使用正确的“强度”不会导致合法用户产生任何真正的烦恼。 这被称为“轮数”或“迭代次数”。 例如,迭代大约一秒就足够了。 假设攻击者可以以系统硬件速度的十倍运行哈希,这可能是安全的。 因此,这限制了攻击者每秒10次的猜测,而不是MD5的20亿次。
关于DoS攻击
是的,您的应用程序执行额外的登录操作可能成为攻击者向您的应用程序提交真正长的密码的目标,或者通过登录请求反复打击它以消耗服务器上的CPU和内存资源。 你有权担心。
这些类型的攻击可通过以下方式进行缓解:
MD5的问题恰恰在于它速度如此之快,您可以使用通用硬件计算约9 Giga MD5 / s。 用大约20万字强力整个英文字典,你只需要几分之一毫秒。
这就是为什么像BCrypt这样的合适的散列算法提供成本因素的原因。 成本因素定义了需要多少时间来计算散列,并且可以在将来被减少。 登录50毫秒并不是一个障碍,但对于蛮力来说这是致命的。
你认为减缓验证是一个问题,但它是抵御泄漏散列和蛮力攻击的唯一防御措施。 现代解决方案反复散列该值(即:数千次)以提高计算成本。
链接地址: http://www.djcxy.com/p/21577.html