【问题标题】:Can a deterministic hashing function be easily decrypted? [duplicate]确定性散列函数可以轻松解密吗? [复制]
【发布时间】:2011-03-10 08:33:39
【问题描述】:

可能的重复:
Is it possible to decrypt md5 hashes?
Is it possible to reverse a sha1?

我问了这个问题: working with HUGE spreadsheet

得到了很好的答案,我听从了建议。我用这个: http://splinter.com.au/blog/?p=86

我在 Excel 电子表格的一列中散列了大约 300,000 个不同的元素

因为你可以做到:

=SHA1HASH('The quick brown fox jumps over the lazy dog')

你会回来的:

2fd4e1c67a2d28fced849ee1bb76e7391b93eb12

你也不能倒退吗?

我说如果它每次都以相同的方式加密相同的文本,那有什么意义呢?

如果你知道哈希算法,是否有可能倒退?

您能简单地向我解释一下散列是如何工作的吗?如何将 20gb 转换为 40 个字符的哈希?散列一个 20gb 的硬盘需要很长时间吗?

【问题讨论】:

  • 这个问题的更好的标题是“可以轻松解密哈希吗?”
  • 谁告诉你可以倒退的?
  • 您是否尝试过倒退?你有没有发现一个实际上确实倒退的函数?
  • 你能逆熵吗?
  • 对于简单的散列,想法是将非常广泛的值映射到具有良好分布的少量值。对于密码散列的想法,很难找到散列的命中值。

标签: algorithm security encryption hash


【解决方案1】:

一般回答

cryptographic hash function 无法轻易撤消。这就是为什么它有时也被称为单向函数的原因。没有回头路了。

您还应该小心调用此“解密”。散列与加密不同。可能的哈希值集通常小于可能的输入集,因此多个输入映射到相同的输出。

对于给定输出的任何散列函数,您无法知道许多输入中的哪一个用于生成此特定输出。

对于像 SHA1 这样的加密哈希,甚至很难找到一个产生该输出的输入。

反转加密散列的最简单方法是猜测输入并对其进行散列以查看它是否给出正确的输出。如果你错了,再猜一次。另一种方法是使用rainbow tables

关于使用散列加密 SSN

对于您的 SSN 用例,由于可能的输入值数量相对较少,因此攻击是可行的。如果您担心人们会访问 SSN,那么最好不要在您的应用程序中存储或使用 SSN,尤其是不要将它们用作标识符。相反,您可以找到或创建另一个标识符,例如电子邮件地址、登录名、GUID 或只是一个递增的数字。使用 SSN 可能很诱人,因为它已经存在并且乍一看似乎是一个唯一不变的标识符,但实际上使用它只会导致问题。如果您出于某种原因绝对需要存储它,请使用带有密钥的强非确定性加密,并确保您保持该密钥的安全。

【讨论】:

  • 不,不可能使用哈希算法。
  • +1,一旦黑了就没有回头路了
  • @Zak 假设您知道这里的目标是 SSN
  • @user 彩虹表有点太复杂,无法在 SO 答案中提供完整的教程(但互联网上有很多关于它们的信息,所以请搜索)。一般的想法是,您预先计算一大堆候选明文的哈希值,然后使用一种巧妙的方法进行反向查找以找到哪个明文对应于给定的哈希值。然而,这种技术很容易被明文“加盐”(在散列之前以一种独特但确定的方式修改它们中的每一个)所击败。
  • @Zak Salting 仅适用于 SSN 等小型域。要求攻击者分别对每一个进行暴力破解会使生活变得更加困难,但域仍然足够小,暴力攻击是可行的。
【解决方案2】:

加密哈希的全部意义在于您无法解密它,而它确实每次都以相同的方式加密。

加密哈希的一个非常常见的用例是密码验证。假设我有密码“mypass123”,哈希是“aef8976ea17371bbcd”。然后,希望验证我的密码的程序或网站可以将哈希“aef8976ea17371bbcd”存储在他们的数据库中,而不是密码,每次我想登录时,网站或程序都会重新哈希我的密码并确保哈希匹配。这允许网站或程序避免存储我的实际密码,从而在数据被盗或以其他方式泄露的情况下保护我的密码(以防它是我在其他地方使用的密码)——黑客将无法倒退从哈希到密码。

加密哈希的另一个常见用途是完整性检查。假设给定文件(例如 Linux 发行版 CD 的映像)具有已知的、公开可用的加密哈希。如果您有一个声称是同一事物的文件,您可以自己对其进行哈希处理,然后查看哈希是否匹配。在这里,它每次都以相同的方式散列的事实允许您独立验证它,并且它是加密安全的事实意味着没有人可以可行地创建一个不同的假文件(例如,其中包含木马)相同的哈希。

请记住散列和加密之间非常重要的区别:散列会丢失信息。这就是为什么你不能倒退(解密)哈希。您可以散列一个 20 GiB 的文件,最终得到一个 40 多个字符的散列。显然,这在这个过程中丢失了很多信息。你怎么可能将 40 个字符“解密”成 20GiB?没有像压缩这样有效的东西!但这也是一个优势,因为要检查 20 GiB 文件的完整性,您只需分发 40 个字符的哈希。

由于信息丢失,许多文件将具有相同的散列,但 加密 散列的关键特征(这就是您所说的)是,尽管信息丢失了,从一个文件开始并构造第二个具有相同哈希的稍微不同的文件在计算上是不可行的。具有相同哈希的任何其他文件将完全不同,并且不容易误认为原始文件。

【讨论】:

  • 这是一个很好的答案!谢谢。如果你知道哈希算法,是否有可能倒退?
  • 不,你不能倒退,这就是重点。原因是散列会丢失信息。我将其编辑到我的答案中。
  • +1 表示“散列丢失信息”,这就是你不能回去的原因!
  • @user29823498750932874509823745- 在反转数学公式、应用哈希和重新生成原始输入的意义上,您不能“倒退”。但是,您可以创建一个包含所有可能输入的表,通过散列函数运行它们,并将输入 + 散列结果存储在一个表中。使用此表反向查找可能生成此输出的可能输入。正如泰勒所说,几个不同的输入会给你相同的输出。即使您有时间/存储空间来生成这样的表格,您仍然有许多可能的输入可供选择。
  • 用户的目标是 SSN 号码。这里的每个人都应该提醒他给他的哈希加盐..
【解决方案3】:

我明白你的观点是基于你试图隐藏社会安全号码这一事实。如果有人知道您在 SSN 上使用 SHA1HASH 来创建唯一标识符,则只需生成所有 SSN 编号的快速列表,对它们进行 SHA1HASH 处理,然后进行比较以自动将人的 SSN 记录在案。更糟糕的是,他们可以在哈希查找表中预先生成所有这些,并且每个 SSN 都有一个 1 个哈希的键。这称为哈希查找表,更复杂的形式称为彩虹表。

这就是为什么发明了散列的第二个功能。它被称为盐渍。加盐基本上就是这样;您创建一个盐,然后使用盐修改您的数据。 例如,假设您拥有 SSN 123-45-6789 。你可以用字符串“MOONBEAM”来加盐。您的新哈希字符串是“123-45-6789MOONBEAM”

现在,即使有人知道您正在对 SSN 进行散列以生成您的唯一 ID,他们仍然不知道您将使用的 salt,因此无法通过预先散列以下列表来推导出原始 SSN所有 SSN 并与您的 ID 进行比较。但是,您始终可以获取用户的 SSN,使用 salt,然后重新哈希 SSN+SALT 以查看用户 SSN 是否与他们的 ID 匹配。

最后,如果您只使用 1 个 salt 并对其保密,而不是能够看到 salt,并通过运行 SSN 增量 + salt 1 亿次并选择匹配来生成相应的 SSN,他们必须做更多的工作来检索 SSN。这是因为 1 亿个 SSN 号码的熵相对较低。 (10^9 组合)。通过添加盐并保密,而不仅仅是运行

SHA1HASH(111-11-1111) -> check hash match
SHA1HASH(111-11-1112) -> check hash match
SHA1HASH(111-11-1113) -> check hash match

他们必须跑

SHA1HASH(111-11-1111a) -> check hash match
SHA1HASH(111-11-1111b) -> check hash match
SHA1HASH(111-11-1111c) -> check hash match
...
SHA1HASH(111-11-1111azdfg) -> check hash match
SHA1HASH(111-11-1111azdfh) -> check hash match
....
SHA1HASH(111-11-1111zzzzzzzzzzzzzzzz) -> check hash match
SHA1HASH(111-11-1112a) -> check hash match
SHA1HASH(111-11-1112b) -> check hash match

.. 以此类推,直到他们最终到达

SHA1HASH(123-45-6789MOONBEAM) -> check hash match

他们终于设法破解了 SSN + SALT

他们甚至不知道你的盐有多少个字符 因此,为了获得 1 个 SSN,他们需要做 10^(salt 的字符数)倍的工作,更不用说获得整个表格了。

更新: 多年后,当我回答这个问题时,我发现我关于盐渍的信息不正确。请在下面的帖子和 cmets 中查看有关每个条目使用唯一盐的正确信息,因为这仍然是链中的第一个帖子。如果您认为我应该在阅读本文后更改 OP,请在下方发表评论(或点赞),如果达成共识,我会更正。

【讨论】:

  • 不是秘密!盐应该附加到散列值,并用于防止字典攻击的预计算。您所指的更像是 HMAC - 在这种情况下,您应该使用适当的 HMAC 而不是这种 ad-hoc 方案。
  • 对存储 H(SSN || salt) 的可能攻击:如果攻击者将自己(或其他人,或虚构的 SSN)注册到系统中,他们可能会找到与其注册对应的行,并且他们的 SSN 的哈希值。由于他们已经知道自己的 SSN,因此他们可以使用此信息来暴力破解盐 (MOONBEAM)。一旦他们知道了盐,他们就可以相对容易地获得其他 SSN。
  • @Zak 秘密盐只是一个实施不佳的 HMAC。盐总是与哈希一起存储。 @Mark Salts,正确使用,是为每个存储值随机生成的 - 一个条目上的盐与另一个条目上的盐没有关系。
  • @Nick Johnson:除非你说的是传统上使用的非秘密盐,在这种情况下,我们谈论的是两种完全不同的东西......也许我还不够清楚吗?我正在回复答案,尤其是这一部分:“他们仍然不知道您将使用的盐”。在我看来,这个答案是有缺陷的,我正在展示对它的攻击。如果您想提出不同的方案,我建议您将其作为单独的答案发布,这样我就可以在那里而不是在这里评论您的方案,这样两个不同的方案就不会混淆。
  • @Mark 如果为每个用户存储一个无意义的标识符就足够了,那么我怀疑 OP 会首先询问散列 SSN。大概他们有一个令人信服的理由为什么他们必须存储 SSN 的哈希。正如我已经说过的,“秘密盐”不是盐——它是一个实施不佳的 HMAC。至于知道盐 - 盐成为散列值的一部分 - HASH(值+盐)+盐。这是非常基本的加密货币。
【解决方案4】:

不,您不能倒退,因为散列函数没有保留足够的信息。

您可以将其视为将原始文本映射到单个巨大数字的哈希函数。这个相同的数字也可以映射到其他文本,尽管一个好的哈希函数很少会发生冲突:

如果原始消息已加密,那么是的,您可以返回。

【讨论】:

    【解决方案5】:

    加密和散列是两个不同的东西。

    散列只是将字符串消化成一个数字。加密保留字符串的内容,以便以后可以解密。没有从哈希中获取原始字符串的方法。内容不存在。

    【讨论】:

    • 'xept 如果你得到了与哈希匹配的所有字符串,然后浏览它们。
    • 我不是数学家,但那不是无穷大的字符串吗?
    【解决方案6】:

    没有。哈希的意义在于它是一种加密方式(正如其他人指出的那样,它并不是真正的“加密”,但请留在我这里)。不利的一面是,理论上,当两个或多个字符串返回相同的哈希时,“冲突”的可能性很小。但这通常是值得的。

    【讨论】:

      【解决方案7】:

      一个好的哈希是一种方式,这意味着你不应该能够倒退。关键是在不泄露字符串的情况下提供字符串的键。例如,这是在不存储密码的情况下匹配密码的好方法。相反,您存储一个散列并比较输入的结果散列。

      【讨论】:

      • 如果你知道哈希算法,是否有可能倒退?
      • 可能,但许多设计都是为了让这变得非常困难。一些算法为不同的输入生成相同的哈希,并且许多(如果不是全部)依赖于输入的长度。您需要了解很多关于被散列的数据才能返回的信息。
      • 这是“普通”散列函数(如您在 python 映射或 java.util.HashMap 中使用)与加密散列函数(如 SHA1)之间的区别。普通散列函数主要针对分散输入中的位(覆盖整个散列输出范围)和效率进行优化。加密哈希还添加了不可逆约束,效率为二阶约束。
      【解决方案8】:

      没有。至少不容易。

      SHA1 仍然被认为是加密安全的。如果哈希算法很容易以一种方式计算,但很难(穷举搜索)以另一种方式计算,则哈希算法是安全的。确实,每次加密特定短语时,都会产生相同的哈希值,但是有无限的短语也会哈希到相同的值。安全性来自于不知道其他短语是什么,直到您通过 SHA1 函数全部运行它们。

      【讨论】:

        【解决方案9】:

        不,你不能回去。计算您可以拥有多少个不同的哈希值。现在计算你可以拥有多少个不同的字符串。第一个是有限的,第二个是无限的。有很多(准确地说是无限多)字符串具有相同的 SHA1 和。然而,关键是很难找到两个具有相同哈希值的文本。

        您可以将散列视为缩短某些内容。例如,采用一个散列函数,它将字符串中字母的所有 ASCII 码相加。你不能知道散列之前是什么,只知道字母的 ASCII 码的总和。它与 SHA1 类似,但更复杂。

        散列的目的不是加密某些东西。散列的目的是缩短一些东西,以便检查两个东西是否相同需要更少的时间。现在,如果您知道很多事物具有相同的哈希值,那么您怎么能说两件事确实是相同的呢?好吧,你不能。你只是假设它是如此罕见以至于它不会发生。

        但散列不仅仅是检查,因为使用散列检查相等性通常仅用于确认/验证,它不是确定性的。如果你看到哈希值相同,那么根据特定哈希函数的参数,你可以估计哈希对象确实相同的概率。

        这就是为什么散列函数总是为相同的对象产生相同的结果这一事实是散列函数最重要的特征。它可以让您验证和比较对象。

        【讨论】:

          【解决方案10】:

          它每次都以相同的方式加密相同的文本是哈希的重点。这是一个特点。

          如果我有一个密码哈希数据库,那么我可以通过对其进行哈希处理并查看哈希是否与我在数据库中为您提供的内容相匹配来检查您输入的密码是否正确。但是,如果有人窃取了我的哈希数据库,他们将无法弄清楚您的密码是什么,除非他们不小心偶然发现了一些哈希到该值的纯文本。

          【讨论】:

            【解决方案11】:

            在密码学中,它被称为摘要。在没有一些额外知识的情况下,加密强摘要不允许根据摘要值获取源文本。同一文本的摘要值相同,因此您可以计算文本的摘要并将其与已发布的摘要进行比较。一个流行的应用程序是密码验证,因此您可以保存摘要而不是密码。这当然容易受到您已经探索过的字典攻击,这就是为什么强烈建议不要使用字典单词作为密码。

            【讨论】:

              猜你喜欢
              • 2015-04-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-02-16
              相关资源
              最近更新 更多