选择哈希或加密密码的困境

时间:2016-12-30 21:17:46

标签: encryption hash passwords

在线阅读了一些帖子和文章后,似乎大多数(如果不是全部)人建议使用某种哈希算法来保证用户的密码安全,因为你不能解开它,这很好,但这就是我开始的地方我的情况有问题。

目前我处于修改用户密码保护方式的早期阶段。我们目前使用 Sha512 在我们的MySQL数据库中存储哈希密码。根据我目前的理解,虽然哈希可能是安全的,因为它们不能反转(或者至少不那么容易),但是由于哈希具有固定长度而不管大小如何,因此也存在不安全性。原始输入,它限制了可能的哈希值,导致Pidgeon Hole问题。

现在又出现了另一个我遇到问题的部分,尤其是我的情况。

我正在尝试为用户的密码添加一些功能,如果用户的密码与他们的最后三个密码太相似,则用户无法输入新密码。例如:如果他们的上一个密码是password1234而他们的新密码是xxxpasswordxxx,则会失败。但是,根据我的理解,我无法添加此功能,因为我无法取消以前的密码来检查旧密码中的子字符串是否在新密码中。这将我带到整个加密/解密部分。

我一直在使用 CBC 加密模式查看 AES 128 ,它似乎是一个可靠的选择,因为我并不十分关心加密中的并行化一部分。另外,通过使用加密路径而不是散列路径,我实际上可以检查它们的最后三个密码是否与它们当前的密码相似!但是,首先存在能够首先看到用户的纯文本密码的问题。

此外,我一直试图想办法为每个密码使用唯一密钥,而不将其存储在我们的数据库中,因为我觉得这太不安全了。我可以使用静态随机密钥来输入所有密码,但我不确定这是不是一个好主意,即使我对所有密码使用唯一的IV。

总结一下我的情况是这样的: 除了实际提高密码存储的安全性之外,我希望能够阻止用户输入类似于旧密码的密码。根据我目前的知识,我可以继续将密码存储为哈希,但我无法进行类似的密码检查或者我可以加密密码,这是不赞成的。 / p>

我显然不是这方面的专家,我知道我需要做更多的研究,但我想确保我的方向正确。

5 个答案:

答案 0 :(得分:6)

关于第二段:哈希冲突绝对不是问题。对于哪种攻击情形,您认为这是一个问题?你应该停止抛出流行语,特别是关于安全性。

您的功能想法会失败,这是部分正确的。这是一个很好的想法,因为这个想法很糟糕。为什么你想要这个“功能” - 它只会惹恼用户并导致人们试图在最后使用数字来规避你的限制,包括月份或其他一些从版本到版本的增量。

加密密码很糟糕 - 周期 只要可以解密它们,攻击也可以 - 故事结束。

您所描述的场景的个人经验:客户端有一个工具,您每2个月就被迫更改密码,我目前在"password"10。我正在做每个人每隔X个月强制更改一次密码的警告 - 只需逐个改变相同的密码。我有一个非常好的密码(15个以上的字符,大写和小写,数字,特殊字符)以及为我设置帐户的任何网站选择密码的系统。强迫我更改密码会破坏我的“系统”,因为现在我不能再一次又一次地在脑中生成密码,因为结果与前两个月网站强迫我设置的内容不符。如果该网站开始引入一些密码相似性限制,我可能会开始写下来。

答案 1 :(得分:4)

为什么不继续使用散列,但要求用户在更改为新密码时输入旧密码,这样您就可以验证旧密码以授权更改密码,然后比较两者的纯文本版本在进行变更之前是否有相似之处?

答案 2 :(得分:4)

当您保留散列密码时,您无法检查类似的密码,但可以防止他们重复使用之前使用过的密码。通过保留旧的(希望是盐渍!)密码,您可以将hash(new_password + old_salt [i])与旧密码的salted_hash [i]进行比较。如果它们相同,则用户重复使用旧密码。

我完全同意其他人认为哈希冲突不是问题。您计划使用SHA512,即攻击者必须与之竞争的512位随机性。你可以打破它的唯一方法是使用rainbow tables并使用盐渍哈希保护自己免受攻击(即使密码相同,盐渍哈希也会产生不同的哈希值;如果使用不同的哈希值则不会出现问题攻击者可以知道salt和hash,所以你可以在一个位置存储salt + salted_hash。)

出于安全考虑,我完全放弃了“类似密码”的事情。如果攻击者获得了大量密码,则更改是数据库中存在大量错误密码。使用启发式和字典攻击,他会有一个很好的改变来猜测你的加密密钥 - >立即解锁所有用户的所有密码。

密码的唯一安全方法是,如果存储密码的系统的操作员也无法恢复密码。其他任何东西只是等待被利用的下一个0天错误。

答案 3 :(得分:3)

  

目前使用Sha512将哈希密码存储在我们的MySQL数据库中

SHA-512 太快。任何获得密码哈希值访问权限的攻击者都可以通过哈希快速运行密码猜测。您需要一个慢速算法,因此每次猜测都需要数千倍的时间。但是,由于您需要对这些密码进行哈希处理,因此您需要选择一个不会使系统过载的值,或者更糟糕的是,测试您的用户'忍耐。使用bcrypt(单独使用)或PBKDF2结合SHA-512(虽然SHA-1 HMAC绰绰有余)。

  

可能存在碰撞

也是不安全的

在您接近系统中的2个 256 用户之前,SHA-512的抗冲击性不是问题。由于地球上的人数甚至不足,我可以肯定地说你的系统会很好。

  

选择散列或加密密码的困境

如果您需要与前者合作,请查看details of the Adobe breach。他们正在加密密码而不是散列。 TLDR;灾害。如果您的系统规模适中,那么您不希望媒体提供有关您系统的任何内容。正确地做事 - 使用PBKDF2或bcrypt - 这样你就可以使用行业认可的方法照顾你的用户,然后就不会因为你的密码存储方案而受到批评。

  

通过使用加密路由而不是散列路由,我可以   实际上,检查他们的最后三个密码是否是   类似于他们现在的那个

好了,因为用户(希望)输入他们之前的密码作为额外的身份验证检查以便更改他们的密码,您可以在此时比较他们的密码,因为您将以明文形式使用它们。例如

old password != new password
lowercase'd letters in old password != lowercase'd letters in new password
adding up all numbers in new password > adding up all numbers in old password + 2 || adding up all numbers in new password < adding up all numbers in old password - 2

也许您希望定义其他规则以防止密码相似性。如果在从第一个密码到第二个密码的更改之间应用这些规则,然后将第二个密码应用于第三个密码,则用户可能会习惯您的规则,并且可能不太可能使其第三个密码与第一个密码太相似。您还可以保留一个密码历史记录表,用于存储其先前X密码(例如四个)的bcrypt哈希值,并进行绝对比较以确保它们不会切换回之前使用过的密码。我不会保留超过四个以防万一他们以前的任何密码都足够破解并且已经在其他网站上重复使用,因为系统上的任何破坏都可能会暴露他们,并且如上所述检查这些密码将是一个缓慢的过程。但是,您可以通过将常用密码加载到系统的黑名单中来确保用户不会选择任何涉及任何违规行为的密码。

加密密码是个坏主意,模糊匹配对所有以前密码的安全优势并不会超过双向加密活动的安全风险(在我看来)。

答案 4 :(得分:2)

要以秘密方式保存密码,您必须使用哈希密码加盐。

对于每个用户,您随机选择一个盐,在数据库中为每个用户保留盐。 您存储在数据库哈希(密码+盐)。

当您必须检查用户的密码时,只需添加salt,哈希并检查数据库。 如果用户更改密码,您也可以更改盐。

以后,您可以根据安全级别选择算法或其他算法,SHA2似乎是一个良好的开端。