joh*_*odo 2 passwords hash md5 sha1
免责声明:关于SO有许多类似的问题,但我正在寻找一个实用的建议,而不仅仅是一般原则.另外,请随意指出"理想"算法的实现(PHP会很好;)但请提供具体信息(如何工作).
计算用于存储在数据库中的密码的哈希字符串的最佳方法是什么?我知道我应该:
我在考虑使用这样的算法:
x = md5( salt + password);
repeat N-times:
x = md5( salt + password + x );
Run Code Online (Sandbox Code Playgroud)
我确信这是非常安全的,但有几个问题浮现在脑海中:
在盐中包含用户名是否有益?
我决定为所有用户使用普通盐,这有什么缺点?
建议的最小盐长度是多少?
我应该使用md5,sha还是其他什么?
上述算法/任何建议有什么问题吗?
...(随意提供更多:)
我知道决定必然取决于具体情况,但我正在寻找一种解决方案:
那么,理想算法会是什么样子,最好是伪代码?
目前,"理想"密码哈希函数是bcrypt.它包括盐处理和可配置的迭代次数.有一个免费的开源PHP实现.
第二好的是PBKDF2,它依赖于底层的哈希函数,有点类似于你的建议.bcrypt比PBKDF2"更好" 有技术原因.
至于你的具体问题:
1.在盐中包含用户名是否有益?
并不是的.
2.我决定为所有用户使用普通盐,这有什么缺点吗?
是的:它消除了加盐的好处.盐的唯一理由是每个散列密码都是唯一的.这可以防止攻击者攻击两个散列密码,而不是攻击一个散列密码的两倍.盐必须是独一无二的.即使每个用户使用盐也很糟糕:当用户更改密码时,也必须更改salt.当盐被重用/共享时,攻击者可以应用的优化类型包括(但不限于)预先计算的哈希表,例如彩虹表.
3.建议的最小盐长度是多少?
盐必须是独一无二的.独特性是一项难以维护的特性.但是,通过使用足够长的随机盐(使用良好的随机数生成器生成,最好是加密强生成器),您可以获得具有足够高概率的唯一性.128位盐足够长.
4.我应该使用md5,sha还是别的什么?
MD5对公共关系不利.它有已知的弱点,可能适用于或不适用于给定的用法,并且很难用任何可靠性来"证明"这些弱点不适用于特定情况.SHA-1更好,但不是"好",因为它也有弱点,尽管不如MD5那么严重.SHA-256是一个合理的选择.正如上面所指出的,对于密码散列,你需要一个在GPU等并行体系结构上不能很好地扩展的函数,并且SHA-256可以很好地扩展,这就是为什么bcrypt中使用的Blowfish衍生物更可取的原因.
5.上述算法/任何建议有什么问题吗?
这是自制的.那很糟.麻烦的是,没有已知的加密算法安全性测试.我们可以期待的最好的事情是让几百名专业的密码学家试图破解算法几年 - 如果他们不能,那么我们可以说虽然算法并没有真正"证明"是安全的,但至少是弱点一定不能显而易见.Bcrypt已经存在,广泛部署并分析了12年.即使在StackOverflow的帮助下,你也无法独自击败它.
作为一名专业的密码学家,我会在MD5甚至SHA-256中使用简单连接引起一个可疑的眉毛:这些是Merkle-Damgård哈希函数,这对于碰撞抵抗是好的,但是不提供随机的oracle(有所谓的"长度延长攻击").在PBKDF2中,哈希函数不是直接使用,而是通过HMAC.