【问题标题】:Generate Same Salt everytime for Same String value每次为相同的字符串值生成相同的盐
【发布时间】:2014-08-12 04:48:12
【问题描述】:

我需要在散列列中添加盐。此散列列还用作其中一个表中的索引。出于显而易见的原因,我不想对所有值使用相同的硬编码盐。

每次为给定的字符串生成唯一的相同盐值的最佳方法是什么,所以当我对值进行哈希处理时,我会得到相同的输出(帮助我使用哈希值进行搜索)。

更新: 感谢大家的投入。 更多细节 - 我必须加密数据库中的一列。该列也用于搜索表中的行,加密后我们不能使用它来搜索,因为我们有可能在以后更改加密密钥。现在为了解决这个问题,我们考虑在表中添加一个哈希列,我们可以在其上执行搜索(因为我们不打算更改哈希算法,我们总是可以将其用于搜索目的)。为了使这个散列列更安全,我们考虑向它添加盐。由于 Salt 应该是随机的,我们将无法每次都为相同的值生成相同的哈希函数,除非我们对所有行使用相同的 Salt。所以这就是为什么我试图找出一种方法,每次都可以为相同的字符串生成相同的盐。 但我认为,在阅读了你们所有的 cmets 和建议之后,我确信这不是一个好的设计,我应该重新考虑我的方法:(

【问题讨论】:

  • 如果您已经在数据库中加密了值,应该很容易找到它。只需在搜索之前加密输入,然后在数据库中搜索加密的值,那么哈希值将完全没有必要。即使搜索不区分大小写也是可能的,添加带有加密小写输入的第二个字段。更改密钥也应该没问题,解密值,用新密钥加密它们就完成了。

标签: java security encryption hash salt


【解决方案1】:

仅使用哈希值作为索引或外键应该没问题(只需在哈希值中包含盐),但我理解,您想重新查找该行,只有原始(未哈希) 值。

这永远行不通,永远不能使用带有适当加盐哈希的列来查找行。这通常意味着设计存在缺陷,散列值不应该是您必须搜索的东西。一个例子:要验证密码,您应该搜索用户名,然后您可以使用找到的密码哈希验证密码。

如果您确定需要搜索此哈希值,那么您唯一的选择是不使用盐(或对所有值使用相同的盐),或加密该值(没有 IV 的双向加密)。当然,与正确散列值相比,这两个选项的保护都较弱。

更新:根据您的更新,您已经在数据库中拥有加密值。这意味着,您可以搜索它,而无需哈希值。只需在进行查询之前加密抢手的值。

【讨论】:

  • @Chris - 当我写“要么不使用盐......”时,我的意思是每个值都没有盐或相同的盐,因为从技术上讲,恒定的盐不是盐。你是对的,IV 遇到了与盐相同的问题。我的实际意思是,如果该值必须是可搜索的,那么在安全性方面总是需要权衡。但如果这是一个要求,那么它就是一个要求。
  • @Chris - 哦,这不是问题,我没有写得更清楚也是我的错。感谢您的评论。
【解决方案2】:

这样做会破坏使用盐的目的。为了达到其预期目的,盐应尽可能随机。

想一想——您可以使用字符串的散列作为“盐”,然后再次将原始字符串和“盐”散列在一起。但生成的哈希仍然是原始字符串的派生词。虽然这可能只为简单的彩虹表提供一点安全性,但这还不够。

http://en.wikipedia.org/wiki/Rainbow_table#Defense_against_rainbow_tables

【讨论】:

  • 我完全同意你的看法,但是现有系统的设置方式我想不出任何其他好的方法。我需要散列也用于索引的列。所以我试图想一些方法,我可以使用某种方式将生成的盐与实际的字符串联系起来。
  • 您能否创建一个新的关系表,其中包含两列,一列带有 ID,另一列带有散列,然后重新设计应用程序的其他部分以使用新 ID 并确定散列?过去在处理散列 SSN 时,我不得不做类似的事情。
  • 我想我不明白。我将如何关联 ID 和实际值?
  • @Chris -- 哇.. 我只是不知道如何对此作出反应。您不应该从原始值中获取盐。您所推荐的充其量是通过默默无闻的安全性,并且违背了使用盐的目的。如果你需要你的哈希是确定性的——不要使用盐。
  • @Chris - 您提出的问题实际上变成了一个安全问题,即通过默默无闻与正确设计的解决方案。如果有人持有您的数据库表,他们很有可能对您的散列过程(源代码或可以反编译的二进制文件)有一些了解。那时,您通过“秘密”加盐技术获得的任何额外安全性都将丢失。所以我认为静态/确定性盐实际上与没有盐一样。把它想象成算法的复杂度 n^2 + 3n = O(n^2) - 3 没有意义。
【解决方案3】:

salt 可以与 salted+hashed 值存储在同一个表中。当你插入一条新记录时,生成一个新的随机盐,盐+散列值,并将散列值和盐保存在该记录中。

【讨论】:

  • 但这无助于搜索加盐+哈希值。
  • 你是对的,它不会。一个好的散列算法的计算速度相对较慢,因此它不是要搜索的字段的好候选。我认为您可能需要重新评估您的架构。如果您更详细地发布了您尝试解决的问题,您或许可以获得替代解决方案。
【解决方案4】:

Salt 不需要特别安全,因此您可以通过使用非加密哈希(可能是FNV hash)从字符串中获取 salt。然后,您可以使用加密散列(如 SHA-256)与盐一起生成安全散列值。非加密哈希还具有更快的优势。

【讨论】:

  • 虽然盐不需要保密,但它不能从原始值派生而来。这将否定盐的目的,因为它只是一个更复杂的哈希函数。然后就可以建立 1 个彩虹表,以获取所有原始值。
  • 然后使用安全的密钥哈希,例如 HMAC。一个秘密主密钥可用于 HMAC 尽可能多的字符串。
  • @rossum:但是 HMAC 没有提供针对彩虹表的保护。
  • @Billy True,但我不清楚提问者需要什么级别的安全性。 HMAC 并不完美,但对于目的来说可能已经足够了。在某种程度上,我们对确切的要求一无所知。
  • @Chris - 如果您使用常量盐,您至少拥有服务器端密钥(pepper)的优势,因为它独立于实际值。如果你从值本身推导出它,那么获取盐的算法(代码)也是一个秘密,但如果你以这种方式构建一个框架,这个秘密将是公共知识。
猜你喜欢
  • 1970-01-01
  • 2010-12-23
  • 2021-09-28
  • 2015-05-16
  • 1970-01-01
  • 2016-05-22
  • 2015-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多