我要把网站转到rails上。这是一个拥有50k+用户的相当大的站点。问题是,现有的密码散列方法极其薄弱。我有两个选择:
1)切换到一种新算法,为每个人生成随机密码,然后将密码发电子邮件给他们,并要求立即更改密码。
2)先实现新的算法,然后使用原有的算法,然后对结果进行散列。例如:
密码: abcdef =算法1=> xj31ndn =算法2=> $21 abcdef 214
任何新的密码都需要经过原始算法(md5),然后如果有意义的话,就会有散列的结果吗?这有什么坏处吗?
发布于 2013-01-18 15:46:16
通常不需要重置密码,只需等到用户下次登录。
每个密码存储系统必须可以选择切换到更好的哈希算法,您的问题不是一次性迁移问题。好的密码哈希算法(如BCrypt )有一个成本因素,您必须不时地增加这个成本因素(因为硬件速度更快),然后您需要与迁移所需的完全相同的过程。
如果您的第一个算法非常薄弱,并且您希望立即提供更多的保护,那么使用散列的选项2是一件好事。在这种情况下,您可以计算双哈希,并将数据库中的旧哈希替换为新的双哈希。
$newHashToStoreInTheDb = new_hash($oldHashFromDb)您还应该标记这个密码哈希(see why),这样就可以将其识别为双哈希。这可以在单独的数据库字段中完成,也可以包含您自己的签名。现代密码哈希函数还包括一个签名的算法,使他们可以升级到新的算法,并仍然可以验证旧的哈希。该示例显示了BCrypt散列的签名:
$2y$10$nOUIs5kJ7naTuTFkBy1veuK0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
___
|
signature of hash-algorithm = 2y = BCrypt核查将按如下方式进行:
new_hash(old_hash($password))进行比较.发布于 2013-01-18 16:53:00
最简单的解决方案可能是将“密码哈希类型”列添加到数据库中。最初将其设置为"old";当用户登录时,使用新算法重新散列密码,并将数据库类型设置为" new“。
此方法的一个变体是将哈希类型存储为哈希字符串的一部分。这也同样有效,只要您能够清楚地区分不同的哈希格式,并且您还可以在同一字符串中包含任何其他所需的参数(如salt和key stretching的工作因子),而不必为每个字段添加额外的字段。
例如,这是modern Unix crypt(3) implementations通常使用的方法(以及各种高级语言(如PHP)中的相应函数):基于DES的经典密码散列看起来类似于abJnggxhB/yWI,而(稍微)更现代的哈希看起来类似于$1$z75qouSC$nNVPAk1FTd0yVd62S3sjR1,1指定了散列方法,z75qouSC是salt,nNVPAk1FTd0yVd62S3sjR1是实际的哈希,选择分隔符$是因为它不能出现在旧风格的DES散列中。
您建议的方法,其中新哈希计算为:
hash = new_hash( old_hash( password ) )在某些情况下可能很有用,因为它允许更新所有现有记录,而不必等待用户登录。然而,只有当旧的哈希函数在密码中保留足够的熵时,它才是安全的。
例如,即使是一个相当老的、弱的密码散列函数(如未加盐的MD5 )也足够好,因为它的输出依赖于整个输入,并且有高达128位的熵,这比几乎任何密码都要多(而且至少足以抵挡暴力攻击)。另一方面,试图使用旧的基于DES的密码(3)函数作为旧哈希函数来应用这个结构将是灾难性的,因为旧密码(3)将忽略每个密码中除前8个字符之外的所有字符(甚至这些字符中最重要的字符)。
发布于 2013-01-18 13:24:43
您可以为使用新密码方法更新其密码的所有用户创建一个新的密码字段,只需使用您的选项2更新每个人。
再加上强制所有用户在登录时更新密码,使用旧密码方法将自动将所有活动用户移动到新密码方法。
https://stackoverflow.com/questions/14399750
复制相似问题