我们需要存储密码(存储的真实信息是一些非常具体的业务信息,但可以将其与密码进行比较以简化问题)。密码应该被散列/加密。
我们不希望能够读取密码,而是希望能够知道哪些用户拥有相同的密码。
如果我们使用始终使用相同盐crypt()
的散列怎么办?CRYPT_BLOWFISH
我们如何对密码进行哈希/加密,并确保如果数据库遭到破坏,攻击者将无法读取或解密它们?
我们需要存储密码(存储的真实信息是一些非常具体的业务信息,但可以将其与密码进行比较以简化问题)。密码应该被散列/加密。
我们不希望能够读取密码,而是希望能够知道哪些用户拥有相同的密码。
如果我们使用始终使用相同盐crypt()
的散列怎么办?CRYPT_BLOWFISH
我们如何对密码进行哈希/加密,并确保如果数据库遭到破坏,攻击者将无法读取或解密它们?
使用密码,您总是在寻找哈希,您不想或不需要解密它们。因此,您正在寻找的是我建议的强大的散列算法、河豚或 SHA512。至于你的不同用户密码比较的问题,那会大大降低系统的整体安全性。
您希望在每个密码中包含一个随机盐,以使无法预先计算哈希值,因此即使是相同的密码也会对每个用户有不同的哈希值,否则攻击者可能会找出哪些用户使用相同的密码并使用它对他们有利。对每个密码使用相同的盐会破坏其目的,并且使用 none 会导致使用彩虹表,因此如果您想要应用程序的安全设计,您将不得不牺牲该特定功能。
编辑:抱歉删除了评论并将其发布为答案
我想如果您正在寻找折衷方案,您会看到很多散列迭代,也许所有密码都有一个大的随机盐。这应该确保没有任何已经可用的预计算表可用于破解密码并增加破解时间。算法链接也可能是一种选择,但如果有很多用户,您可能会遇到性能问题。本质上,如果您仍然希望能够比较用户密码,那么计算哈希值会很耗时,这会从根本上增加破解时间。再次强调,这将是一种妥协,绝对不是解决这个问题的最有效和最安全的方法。
您需要一个 salt 和 bytes 数组来存储敏感信息。然后,您可以使用存储在其他地方的主密钥安全地加密该对。使用 2 阶段加密,您可以出于安全目的随时滚动您的密钥。您的应用程序需要能够组合这些部分来比较数据。
使用密码,我和 SO 和其他网站上的许多其他人强烈推荐 Bcrypt;Bcrypt 是一种计算密集型散列算法,其设计速度慢且暴力破解成本高。
您可以在此处阅读有关 Bcrypt 的更多信息: How do you use bcrypt for hashing passwords in PHP?
至于比较值,你不能用 Bcrypt,但你可以检查值是否正确。
这完全取决于您的业务信息是什么。您已经看到,散列比加密更可取,因为它无法解密(否则您会提出不同的要求)。
您不能像密码一样散列信息的问题是盐是唯一的,因此散列函数会导致无法比较的散列值。如果我们可以不用盐,我们可以为您的目的使用哈希函数。
腌制完成,因为密码通常是短文本(人们必须记住它们)。通过检查字典或彩虹表,我们可以非常快地找到原始密码,但没有现有的用于盐+密码文本的彩虹表。换句话说,具有一定长度的非常强的密码不需要加盐来保证安全。如果您的业务信息有足够的唯一信息(熵),您可以在没有盐的情况下进行散列并使用 BCrypt 或 PBKDF2。