0

是否存在幂等的哈希函数?我知道 MD5 和 SHA256 不是:

$ echo -n "hello world" | md5sum
5eb63bbbe01eeed093cb22bb8f5acdc3  -
$ echo -n "5eb63bbbe01eeed093cb22bb8f5acdc3" | md5sum
c0b0ef2d0f76f0133b83a9b82c1c7326  -

$ echo -n "hello world" | sha256sum
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9  -
$ echo -n "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9" | sha256sum
049da052634feb56ce6ec0bc648c672011edff1cb272b53113bbc90a8f00249c  -

有没有可以做这样的事情的哈希算法?

$ echo -n "hello world" | idempotentsum
abcdef1234567890
$ echo -n "abcdef1234567890" | idempotentsum
abcdef1234567890

如果确实存在这样的算法,它在密码学上是否有用?即有合理的输入,用已知输出猜测输入在计算上是不可行的吗?

如果这样的算法不存在,它不存在是因为没有人费心去寻找它,还是在数学上不可能?

语境

我正在开发一个用户可能希望在密码管理器中保存密码的系统。特别偏执的用户可能更喜欢以散列形式而不是纯文本形式保存密码。我希望用户能够使用此散列密码进行身份验证。而不是简单地尝试两次身份验证(一次假设用户的密码被散列,一次假设它不是),我想知道是否有一种算法让我只做一次。

我知道有允许用户存储身份验证令牌而不是纯文本密码的替代方法。但是这个想法突然出现在我的脑海中,我很好奇。我在 Google 或 SO 上找不到任何关于此的内容。

编辑:我并不是建议允许用户使用散列密码进行身份验证意味着服务器不加盐/散列密码是可以的。服务器仍必须对原始密码或客户端哈希密码进行加盐/哈希处理。

编辑:我并不是说允许用户使用客户端哈希密码登录是真正的安全改进。据我所知,这将增加的唯一可能的好处是,如果用户将此密码用于多个目的。在这种情况下,如果攻击者发现了用户的哈希密码,那么只有对我的服务的访问会受到威胁,而不是所有共享该密码的服务。但是,最佳做法是不要对多个服务使用相同的密码。

4

2 回答 2

1

这样的函数实际上很容易找到,并且不会削弱系统的密码学(除了以明显和微不足道的方式)。我们实际上可以将任何散列函数转换为幂等散列函数,只要我们有一种方法来识别给定值是否是散列函数的潜在输出(用更正式的语言,如果域的元素也是范围)。

(这样做的一个潜在方法是检查输入元素的大小,因为大多数散列函数试图统一输出直到给定大小的值。这忽略了错误识别一个永远不能从散列函数输出的值的可能性,但这将特定于单个散列函数。)

然后我们创建一个新方法来检查一个值是否可以从散列函数中输出,如果可以,则返回该值。否则,该函数正常运行并对值进行哈希处理。这个新函数与原始函数一样安全,除了其范围的散列值,它完全不安全,但这在幂等散列函数中是不可避免的。

于 2018-08-07T21:02:11.710 回答
0

如果确实存在这样的算法,它在密码学上是否有用?

好吧,考虑一下:散列通常是两个集合之间的映射:

A -> B

其中 B 是可能散列的集合,A 是可散列的事物的集合。

现在,通常 A 比 B 大得多——哈希就像更短的“校验和”,可以从更大的数据流中计算出来。通常,您仍然希望哈希中的冲突尽可能少,这意味着从统计上讲,来自 B 的所有元素应该具有相同数量的来自 A 的映射到它们的元素,并且来自 A 的元素映射到相同的元素B 在某些度量下应该彼此“远离”。这意味着,B 尽可能努力地使整个单词集具有恒定长度。很难找到一个系统函数来做到这一点,但仍将 B 中的每个元素映射到 B 中的相同元素;你“强制”碰撞。一般来说,这是一个加密弱点,而且是一个严重的弱点。

现在,考虑您的密码情况:我不明白这有什么意义。让您的用户使用他/她的散列密码或明文进行身份验证在密码学上是一个坏主意,因为无论您做什么,您都会向所有窃听者泄露有关如何伪造身份验证的完整信息。

于 2015-04-25T19:34:08.127 回答