Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Security 如何在现有web应用程序中逐步淘汰密码哈希算法?_Security_Web Applications_Encryption_Password Protection - Fatal编程技术网

Security 如何在现有web应用程序中逐步淘汰密码哈希算法?

Security 如何在现有web应用程序中逐步淘汰密码哈希算法?,security,web-applications,encryption,password-protection,Security,Web Applications,Encryption,Password Protection,很多人都在讨论(web)应用程序中的密码,但我遇到了一个不同的问题。我知道我目前正在开发的应用程序不够安全(只是不含盐或任何东西的sha1),但是突然改变它有点困难 我必须找到一种方法,为所有(±50000)用户实现一种新算法。我一直在考虑一些解决方案,但没有一个听起来是对的 1) 使用新密码向用户表中添加第二列。每次用户通过身份验证时,我都会将密码与其新哈希一起存储,并丢弃旧的密码。这实际上意味着sha1将需要数年时间才能逐步淘汰 1.1)执行上述操作,但刺激用户重新登录到我们的系统进行安全更

很多人都在讨论(web)应用程序中的密码,但我遇到了一个不同的问题。我知道我目前正在开发的应用程序不够安全(只是不含盐或任何东西的sha1),但是突然改变它有点困难

我必须找到一种方法,为所有(±50000)用户实现一种新算法。我一直在考虑一些解决方案,但没有一个听起来是对的

1) 使用新密码向用户表中添加第二列。每次用户通过身份验证时,我都会将密码与其新哈希一起存储,并丢弃旧的密码。这实际上意味着sha1将需要数年时间才能逐步淘汰

1.1)执行上述操作,但刺激用户重新登录到我们的系统进行安全更新,但这真的让人觉得承认了(预)安全漏洞。我的管理层不喜欢这样

2) 重新验证所有用户并丢弃所有密码。这是非常严格的,也是用户的后遗症


您将如何处理此问题?

我将按照您建议的方式首先处理:每当用户进行身份验证时,存储新的哈希并丢弃旧的哈希。您不必将新的散列放在单独的数据库列中;相反,您可以添加一列,该列只说明散列的格式,并对实际散列使用相同的列,而不管其格式如何

您不必为了更新密码哈希而强制用户登录,但将来可能会发生其他事件(如不相关的安全漏洞),这为重置密码或让所有人都登录提供了更好的理由


一年后,任何仍然使用旧格式的密码哈希的人都是一年没有登录的人。向他们发送提醒电子邮件并最终删除未使用的帐户可能是一个好时机。

您可以将sha1哈希作为新的改进哈希实现的输入来扩展现有的解决方案,您可以在其中添加salt等。然后,新的解决方案将包括sha1步骤+您可能需要的任何改进


通过这种方式,您可以从已有的哈希值计算新的哈希值,但同时改进解决方案。

每个密码存储系统都必须选择切换到更好的哈希算法,您的问题不是一次性迁移问题。好的密码散列算法,如BCrypt或PBKDF2,有一个成本因素,有时您必须增加这个成本因素(因为更快的硬件),然后您需要与迁移完全相同的过程

$2y$10$nOUIs5kJ7naTuTFkBy1veuK0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
 |  |  |                     |
 |  |  |                     hash-value = K0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
 |  |  |
 |  |  salt = nOUIs5kJ7naTuTFkBy1veu
 |  |
 |  cost-factor = 10 = 2^10 iterations
 |
 hash-algorithm = 2y = BCrypt
今天的密码库通常会生成一个包含所有参数(如salt和cost factor)的字符串。生成此格式的原因正是为了在不丢失现有密码的情况下切换到更安全的算法。验证过程知道用于验证的算法,因此您可以看到这确实是一个“正式”解决方案

$2y$10$nOUIs5kJ7naTuTFkBy1veuK0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
 |  |  |                     |
 |  |  |                     hash-value = K0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
 |  |  |
 |  |  salt = nOUIs5kJ7naTuTFkBy1veu
 |  |
 |  cost-factor = 10 = 2^10 iterations
 |
 hash-algorithm = 2y = BCrypt
通常不需要重置密码,只需等待用户下次登录,就可以获得明文密码并计算更安全的哈希。如果现有的散列非常弱,比如在您使用非盐SHA-1的情况下,那么您可以通过对旧散列进行散列立即提供更多的保护,这对于非盐散列尤其容易

$hashToStoreInDb = new_hash($weakUnsaltedHashFromDb);
为了进行验证,您可以:

  • 首先尝试用新算法验证输入的密码
  • 如果不匹配,请将其与双哈希算法比较
    new\u hash(old\u hash($password))
  • 如果双哈希值匹配,则可以计算并存储更新后的哈希值

  • 确保首先检查最新的算法,然后检查较旧的算法。然后,只有在用户下次登录时,登录时间才会更长,并且新用户不会受到向后兼容性问题的影响。当然,您也可以使用上面的格式,将其标记为双哈希。

    我不知道为什么我没有想到这一点,但这真的很聪明。这样就省去了很多麻烦。谢谢但它仍然会在散列算法中留下愚蠢的遗留crud。我建议将此作为对现有散列的一种转换措施,但对所有新散列使用更干净的算法,以便最终删除旧散列。据我所知,您建议将pbkdf2(salt,sha1(passwd))存储在数据库中,然后对sha1列进行重映射。我认为这是个好主意。事实上,鉴于heartbleed漏洞,有人可能会争辩说,用户密码永远不应该直接在服务器端处理,而应该进行客户端处理。在客户端执行sha1将是朝着正确方向迈出的一步(如果我们可以在客户端执行所有操作,那会更好,但这比我在这里解释的要复杂一些)。