【问题标题】:Is there an idempotent hash function?是否存在幂等哈希函数?
【发布时间】:2015-07-04 08:29:48
【问题描述】:

是否存在幂等的哈希函数?我知道 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

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

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

上下文

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

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

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

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

【问题讨论】:

  • 我不认为想要保存哈希密码的用户是偏执狂
  • @AndrewMedico:维基百科说:幂等性(/ˌaɪdɨmˈpoʊtəns/EYE-dəm-POH-təns)是数学和计算机科学中某些操作的属性,可以多次应用而不会改变超出初始申请的结果。我认为这绝对是正确这个词。
  • 用户以散列形式保存密码是没有意义的。如果服务器接受特定字符串进行登录,则根据定义,即“明文密码”。它是随机词还是散列的输出都没有关系。这实际上对安全性更不利,因为如果有人获得了登录数据库的副本(例如,可能是丢失的备份磁盘),他们可以立即以任何用户身份登录 - 无需费心破解哈希。
  • @Krab 我不使用“偏执狂”这个词来必然意味着任何不好的事情。我可以改用“安全意识”这个短语。但我认为有安全意识的用户会知道为每个网站使用唯一的密码。据我所知,这样做会否定在客户端散列密码的任何好处。
  • @AndrewMedico 我并不是说散列密码客户端消除了再次散列密码服务器端的需要。服务器肯定需要对密码进行加盐/哈希处理。我确实同意,在这种情况下,用户实际上拥有两个密码。散列密码客户端的唯一要点是用户是否与其他服务共享此密码(这当然是个坏主意)。我提供了上下文以更好地解释我是如何得出这个问题的。我实际上并不认为这是我正在寻找的算法的一个很好的用例。我将进行编辑以使这一点更清楚。

标签: hash idempotent


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

    A -> B
    

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

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

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

    【讨论】:

    • 我同意基于密钥的身份验证(例如 SSH)比使用密码更好。但是现在几乎每个网站都允许用户使用他们的纯文本密码进行身份验证——包括大多数网上银行。对于没有采用客户端 SSL 证书,我和下一个人一样不满意。但我怀疑原因是,将客户端密钥复制到每台设备对于普通网络用户来说实在是太高了。
    猜你喜欢
    • 2023-02-02
    • 2015-02-21
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 2011-02-04
    • 2011-05-05
    • 1970-01-01
    相关资源
    最近更新 更多