【问题标题】:In Hashing, can't we find AT LEAST one original text hashing to the given hash value在散列中,我们不能找到至少一个原始文本散列到给定的散列值吗
【发布时间】:2021-06-17 18:55:55
【问题描述】:

我有一个关于散列的基本问题。据说散列是一种方法。我有一个疑问,如果我们只是简单地颠倒程序/算法/逻辑中的步骤,那么我们不能找到至少一个哈希到给定输出哈希值的输入吗?。

我找到了2个相关的帖子,但我仍然不完全清楚:

How is one way hashing possible?

How do one-way hash functions work? (Edited)

我的问题与第一篇文章中对已接受答案的评论相同:

“好吧,但是如果我想绕过密码检查,只要找到一个哈希值与原始密码相同的字符串就足够了”。这个评论站得住脚吗?

【问题讨论】:

  • 我不清楚您的问题是什么,您声称的问题是陈述。如果您认为您可以反向运行程序,为什么不选择一个哈希函数并尝试一下呢? (请注意,为 SHA-256 有效地实现这一点会让你变得富有,因为你将能够挖掘比特币)。
  • @PaulHankin :我们不能通过手动计算手动反向运行算法吗?我们可以手动计算算法中每一步的输入和输出。
  • @grit639:并非所有数学运算都是完全可逆的。
  • 如何反转a=b?你不知道a 以前是什么。您可以选择一个值,但它可能与代码中的任何路径都不兼容。
  • 一个更好的例子:假设哈希函数是integer hash(integer k) { return pow(65537, k, M) },其中 pow(65537, k, M) 是 65537 的 k 次方 M (其中 M 是两个大素数的乘积), integer 是一个 4096 位整数。你如何扭转它?这个功能难以逆转是 RSA 加密起作用的原因。

标签: algorithm security hash cryptography cryptographic-hash-function


【解决方案1】:

您所想的是所谓的“哈希冲突”。

你的想法是对的,如果人们可以找到一种有效的方法来确定给定哈希函数的输入,从而产生所需的输出,这将破坏很多系统 (https://en.wikipedia.org/wiki/Preimage_attack)

这就是加密安全散列函数的基本内容。这些函数的构建方式是非常非常难以找到产生所需散列的原像。

随着时间的推移,数学家和密码学家正在逐渐消除这些哈希值,并且许多用于保护事物的哈希函数已被破坏(MD4、MD5、SHA-1)。

此外,区分用于检查消息完整性的哈希值和用于保护机密的哈希值也很重要。

对于完整性检查,您需要 快速 散列,以便您可以轻松地将大量数据放入其中。 MD5、SHA-1、SHA-2 就是这样的哈希。

对于保密,您希望 SLOW - 比糖蜜哈希值更好,这样人们就无法轻易通过其他可预测的秘密模式的字典进行暴力破解。 SCrypt、BCrypt、Argon 和多轮 PBKDF 方案就是这样的哈希。

【讨论】:

  • “这就是加密安全散列函数的骨干。它们的构建方式是非常非常难以找到产生所需散列的原像。” =>>您能否给出一些无法反转的函数/程序步骤的具体示例,以找到一个将映射到给定哈希值的输入。假设算法是开源的,难道我们不能把程序的每一条语句都倒过来,从而找到至少一个有效的输入吗?
  • 最常见的例子(也是一个容易理解的例子,也常用于密码系统)是离散对数:en.wikipedia.org/wiki/Discrete_logarithm 如果每个有效算法都有一个有效逆,那么足以证明 P=NP (en.wikipedia.org/wiki/P_versus_NP_problem)。常见的例子是数独难题很难解决,但很容易证明给定的解决方案是有效的。
  • 我意识到一个更好的例子,它更容易理解,就是素数分解。将两个 n 位值相乘可以在
【解决方案2】:

加密散列函数中的操作非常复杂,而且数量如此之多,以至于反转函数(为给定的输出计算至少一个有效输入)是非常不可行的。无论您是手动进行还是借助某种算法求解器来进行反转都没有关系。这被称为(第一)原像抗性,这是密码学家在提出新的散列函数时所攻击的内容。如果哈希函数经受住了时间的考验,则被认为是安全的。

另一方面,生成一堆候选密码并在它们上运行已知的哈希函数以检查与给定输出的相等性要容易得多。人类不擅长生成好的密码或密码短语。看看这个talk

在散列中,我们不能找到至少一个原始文本散列到给定的散列值

在这种情况下,暴力破解输入空间的“查找”比攻击哈希函数本身更容易。

【讨论】:

    【解决方案3】:

    有一种非常简单的方法可以给出不可逆的哈希函数:

    int GetHashCode(byte[] myData)
    {
        return 1;
    }
    

    这是一个完全有效的哈希函数,因为它将任意数据集的内容映射到一个小得多的域(在这种情况下为int)。它满足相同的输入数据给出相同的输出数据的条件。

    显然这个函数是不可逆的。

    (当然,这个散列函数并不适合保护任何东西,但这只是散列函数的一种应用)

    【讨论】:

    • 我正在考虑将散列用于密码并且散列值存储而不是原始文本密码的应用程序。在这种情况下,如果有人可以访问数据库并看到哈希值,则无法通过反向跟踪,他可以找到至少一个文本密码,该密码将哈希为相同的值,因此他可以使用该密码登录。在您的示例中,有效的原始密码可以是任何文本。
    • 是的,没错。但我回答的是“单向”部分。
    • 虽然这很好地说明了单向性,但该示例很快就崩溃了,因为我们关心加密哈希函数的原像抗性。使用这个函数,我可以找到无数个,但至少有一个有效输入会产生已知且所需的输出。
    • @ArtjomB。当然,为了安全起见,我的函数确实很糟糕,但它指出了一个函数是如何不可逆的。
    猜你喜欢
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 2014-07-27
    • 2016-09-04
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    相关资源
    最近更新 更多