如何处理不能随机的盐?确定性腌制策略

时间:2018-05-30 18:13:43

标签: security hash architecture salt deterministic

考虑以下情况:

  • 用户在网站上输入唯一代码(比如礼品卡)。
  • 代码对应于数据库中必须检索的对象。
  • 代码是秘密,不能以纯文本形式存储。
  • 相反,代码将被散列并存储在数据库中。哈希算法将是sha-512或bcrypt与一些腌制策略相结合。

为了查找代码,必须使用用户输入的代码的哈希值。通常,在密码认证的情况下,用户的身份是已知的,因此可以在计算散列之前从数据库中检索盐。在上面的场景中,虽然无法加载与代码关联的salt,因为我们不知道代码对应的数据库中的哪个对象。这似乎暗示对于这种情况,盐可以是随机的,没有这种腌制策略。

我想就以下想法提出意见:

我们可以哈希(例如sha2)用户输入的代码作为盐吗?

salt = sha2(code)
hashedCode = hash(code + salt)

如果有上述漏洞,可以包括一些额外的全局秘密作为哈希的一部分帮助减轻风险吗?

salt = sha2(code + globalSecret)
hashedCode = hash(code + salt)

谢谢!

2 个答案:

答案 0 :(得分:2)

哈希是绝对错误的做法。我将在一秒钟内完成,但首先让我解决数据库问题中的查找。

在db问题中查找秘密

大多数礼品卡在正面都有代码,背面有防刮秘密的原因解决了这个问题。

用户在前面输入代码。然后你的应用程序提取数据库记录。然后用户在背面输入刮开代码。您可以将该代码与数据库中的代码进行比较。

另一种方法是拆分代码,使第一部分是数据库记录ID,第二部分是要比较的代码。例如:

1234 5511 2121 1234 --- 12345511是记录ID,21211234是密码。

哈希是错误的方法

所有这些都与关于哈希的问题无关。我们建议您使用哈希密码,因为我们不希望有人获取数据库并反转密码,然后将这些密码用于其他网站。

在您的场景中,您可能最终处于某人窃取您的数据库的状态,然后能够猜出所有代码。好吧,这是你的解决方案的问题。如果我知道代码在1到100000000之间,那么我可以计算1到100000000,计算每个代码的散列/密码,并恢复所有代码。我可以在几分钟内完成。除非您发送2 ^ 128个长度代码(我从未输入),否则解决方案完全有缺陷。

当然,这就是为什么他们有盐的价值。因此,我必须转到每个礼品代码哈希,并运行所有10000000值。但这仍然是几个小时的工作,而不是你想要的几年。盐根本无法解决问题。

那么怎么做呢?

如果您的风险是有人窃取数据库,然后使用所有礼品代码来窃取资金,则会发生以下两种情况之一。你要么取消所有的代码(然后一群拿着礼品卡的人生气),要么保护代码。

您希望使用HMAC,而不是以明文形式存储代码,或者代码哈希(基本上是明文,因为我可以在几分钟内枚举所有可能的值)。 HMAC是哈希和密钥。

giftcode_in_db = HMAC(<SECRETKEY>, giftcode_from_user)

现在,为了保护您的所有礼品代码,您只需要保护密钥。只能在内存中使用它,让操作员手动输入或使用Hashicorp Vault进行实际的HMAC操作。

如果有人窃取您的数据库,他们还需要窃取密钥。如果有人窃取了密钥,他们还需要窃取数据库。

答案 1 :(得分:1)

如果您的16个字符的字母数字代码(0-9 a-z A-Z)是真正随机生成的,它们非常强大,即使使用像SHA-256这样的快速哈希算法也可以进行散列和存储而不需要进行腌制。

可以提高使用服务器端密钥的安全性,无论是加密哈希值,还是使用HMAC都不是那么重要。重要的是,攻击者在开始破解之前需要服务器上的其他权限来获取密钥(SQL注入是不够的)。

如果代码较弱(较短),您也可以使用按键拉伸,以增加强制执行所需的时间。即使代码不是太短,单个计算甚至几毫秒也会阻止暴力攻击。键拉伸可以独立进行腌制。当然更好的是使用足够强大的代码。