你有一个纯文本密码和盐。假定纯文本密码是安全随机的,只有用户知道,salt 不是秘密,不一定是唯一的,而是与生成的哈希一起存储。单独调用以下内容并存储结果是否足够?
password_hash = Hash ( password || salt )
凡Hash
目前被认为是“安全的”散列函数(SHA512,BCrypt等)
人们做得更多吗?如:
- 多次迭代:运行多次迭代有巨大的好处吗?如果是,这纯粹是成本优势吗?迭代次数是动态的还是静态的?多少次迭代?
- 多个散列函数:使用多个散列函数会有优势吗?例如,三轮,
sha512 -> BCrypt -> sha512
? - 盐混合人们是在密码中嵌套盐还是在结束/开始时连接?例如,将普通密码分成四个部分,盐分成三个部分,并在每个密码部分之间加入每个盐部分。
- 独特的方案
password_hash
:为每个不同的项目编写一个独特的函数会有什么好处吗?例如,项目 A 的password_hash
函数运行 SHA512 20 次,项目 B 的password_hash
函数运行 BCrypt 10 次,在每次迭代时在密码的不同端应用盐。 - “黑魔法”:将自己的“黑魔法”添加到散列函数中是否有好处?例如,在每次迭代之前,您应用一些基本的按位操作或基于简单算法混合字符。
- 混淆:对生成的哈希进行编码或混淆以隐藏其原始哈希函数会产生巨大的影响吗?例如在哈希中添加或删除 N 个字符以隐藏其原始长度。
这些行动真的有必要吗,它们会产生巨大的影响(如果是的话,以什么方式),人们在实践中是否使用了像上面提到的任何额外的行动?
我的想法:
最后,无论使用密码做什么都不会阻止某人使用愚蠢的密码(如“密码”或“123”);必须采取与该问题无关的其他方法。但是有可能通过多次迭代使计算成本更高,从而减慢速度或使暴力攻击变得不可行。
上面提到的大多数操作将对已经获得用户列表访问权限的人产生很大的影响——电子邮件、密码哈希和盐,并希望恢复纯密码。它不会阻止一个坚定的黑客,但会阻止并希望减慢他们的速度,让您有足够的时间进行适当的更改或采取措施来保护被入侵的帐户。
然而,这在很大程度上违背了“攻击者无所不知”的想法。假设攻击者可以看到密码散列是如何生成的(源代码和模式),那么差别不大。这与将数据库表的列名从更改为一样password
重要ahoy
无论如何,只是使用password_hash = Hash ( password || salt )
似乎太简单了。人们肯定做得更多吗?