【问题标题】:How does password encoding work?密码编码如何工作?
【发布时间】:2011-08-19 18:13:18
【问题描述】:

我知道这不是一个好标题,我不希望任何人真正知道具体细节。

我特别指的是 PHP 的 md5 函数,它将密码更改为 32 位字符串,我认为...
无论如何,如果我有诸如“打字机”之类的密码,md5 函数会始终将其编码为完全相同的字符串吗?如果是这样,那么确定所有单词的编码并找到某人的密码肯定很容易吗?如果有一个函数可以对一个单词进行编码,那么肯定会有一个函数可以快速解码它......

什么是对用户密码进行编码最安全的方法,我读到过使用 salt 方法将另一个字符串附加到用户密码,但如果他们可以解码密码,他们肯定可以将 salt 解码为?

感谢您的宝贵时间,期待您的建议。

P.S 不确定是否很容易为此授予获胜者,因为这是一个相当开放的问题。

【问题讨论】:

  • MD5 实际上是一个 128 位的散列,大部分时间表示为 40 个字符的字符串。也就是说,这可能是“Secure hash and salt for PHP passwords”的副本
  • 40?我看到大部分是 32 个字符串。不与 SHA1 混淆?

标签: php passwords md5


【解决方案1】:

无论如何,如果我有诸如“打字机”之类的密码,md5 函数会始终将其编码为完全相同的字符串吗?

是的

如果是这样,那么确定所有单词的编码并找到某人的密码肯定很容易吗?

没有。关键是哈希是单向的。 (简化示例:3x5=15。知道 15,你必须乘以第二个数字得到什么?)危险在于彩虹表,人们已经计算出散列许多不同输入的结果,所以你可以做反向查找。

对用户密码进行编码最安全的方法是什么

使用盐

,我读到了关于使用 salt 方法将另一个字符串附加到用户密码的信息,但是如果他们可以解码密码,他们肯定可以将 salt 解码为吗?

为每个密码使用不同的盐。

【讨论】:

  • 由于 salt 没有真正定义,salt 是一个常量字符串(如 foobar),您总是将其塞入哈希中,如 md5($string . $salt)。它阻止了彩虹表攻击,因为如果md5($string . $salt) == md5($password . $salt),那么你可以放心地假设$string == $password
  • 我总是更喜欢digest($salt . digest($password)) 这样的东西,其中摘要是您选择的任何哈希算法(md5、sha1 等)......有些网站甚至将用户名或用户 ID 等内容作为哈希的一部分.使用 sha-256 之类的东西应该足以涵盖反向查找的问题(至少目前如此)
【解决方案2】:

md5 函数不是为密码加密而设计的——它是一种单向散列函数,允许在两个(可能很大的)字符串之间进行快速比较。

通过暴力破解密码的计算成本非常高,即生成大量密码并对其进行散列处理,直到匹配成功。

md5算法已被破解——无需暴力破解即可轻松逆向。

md5 函数每次都会为两个相同的字符串生成相同的哈希值。它还可能为两个不同的字符串产生相同的哈希值 - 读取哈希冲突。

【讨论】:

    【解决方案3】:

    md5 密码每次都会创建相同的加密密码。

    尝试使用 phpass 以获得更高的安全性。它使用盐和其他散列算法,例如河豚。

    阅读更多关于phpass

    也可以单独使用河豚。检查php crypt

    【讨论】:

      【解决方案4】:

      至少,它们将编码相同,因此很容易通过“rainbow tables”进行暴力攻击

      正如您所提到的,您可以将 a salt 添加到哈希中,这会有所帮助。

      您可以改为加密它们,但这也有风险。

      坚持使用哈希。

      祝你好运。

      【讨论】:

        【解决方案5】:

        无论如何,如果我有诸如“打字机”之类的密码,md5 函数会始终将其编码为完全相同的字符串吗?

        是的

        如果是这样,肯定很容易找出所有单词的编码并找到某人的密码吗?

        不,不是没有额外资源。有彩虹桌;这些是带有 hash=>password 的表,这在这里很有帮助。通过蛮力,他们只需将密码的哈希值与表中的所有哈希值进行比较,并且可能存在匹配,从而产生可读的密码。

        如果有一个函数可以对一个单词进行编码,那么肯定会有一个函数可以快速解码它......

        MD5 既不是加密也不是编解码器。它是一个散列函数,这意味着您无法对其进行解密或解码,因为理论上存在无限的字符串候选者,这会导致相同的散列。这也是为什么你需要彩虹表和暴力破解哈希的原因。

        什么是对用户密码进行编码最安全的方法,我读到过使用 salt 方法将另一个字符串附加到用户密码,但是如果他们可以解码密码,他们肯定可以将 salt 解码为?

        就是这样。

        $hashed = md5($pass . "MySalt");
        

        (使用可购买的硬件;))解密它几乎是不可能的。如果你有一个超级杜帕重要的网站,有人可能会为你的盐创建一个特殊的彩虹表(如果他们知道的话)。在这种情况下,您可以使用随密码一起保存的随机加盐。

        【讨论】:

          【解决方案6】:

          对于相同的输入,哈希函数将始终具有相同的输出。
          您不必担心解码诸如 md5 或 sha1 之类的哈希函数。
          如果您认为有人可以解码您的散列密码,您可以使用“盐”和/或组合散列,例如:

          $pass = "password";
          $salt = "salt";
          $encodedPass = sha1(md5($pass.$salt));
          

          【讨论】:

            【解决方案7】:

            http://codahale.com/how-to-safely-store-a-password/

            安全密码存储很难。加盐和使用像 SHA-1 这样更强的哈希比直接的 md5 哈希有一些优势(彩虹表使这变得容易),但这仍然不是一个很好的解决方案。使用 bcrypt 之类的东西来保证安全,也不要尝试编写自己的加密代码。

            【讨论】:

              【解决方案8】:

              使用从任何字符串产生确定性结果的单向函数对密码进行哈希处理,这就是哈希的全部意义:与其存储值,不如存储一些派生消息并检查用户输入的哈希值是否匹配存储在用户存储库中的哈希。

              您提出的问题 - 有人创建了一个包含所有单词及其哈希值的字典,从而可以反向查找哈希值,这当然是一个必须解决的问题,也是许多登录系统要求您选择非单词密码的原因。

              一个好的散列函数的另一个因素必须是即使输入(密码)的微小变化也会导致散列发生重大变化。通过这种方式添加数字或更改大小写将产生巨大的新输出,并且创建字典的工作将更加困难。使用 md5 哈希的示例:

              密码:5f4dcc3b5aa765d61d8327deb882cf99

              密码:a61f3f0aee2e87cf0571ca70afe289d2

              请放心,包含“test”“password”“mommy123”等的字典已经存在。

              除了 md5 不是一个非常安全的哈希函数之外,使用 SHA1 或 SHA-256 可能是更好的选择。

              【讨论】:

                【解决方案9】:

                不要使用 MD5。使用 SHA1 或 SHA256 或 MD5 以外的其他东西,因为 MD5 没有那么安全。我不知道 SHA1 的安全级别(毕竟,他们确实制作了 SHA256),但我知道 MD5 的“安全性”,那就是它被发现需要。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-01-06
                  • 1970-01-01
                  • 2013-02-28
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多