【问题标题】:php crypt - trailing dollar sign - extract only the salt part from hash - padding the saltphp crypt - 尾随美元符号 - 仅从哈希中提取盐部分 - 填充盐
【发布时间】:2023-04-28 22:58:01
【问题描述】:

我正在阅读PHP's crypt() 函数。我有几个问题 -

  1. 我在大多数示例中看到的盐字符串末尾的尾随“$”符号的意义是什么。该手册没有具体说明用它来结束盐字符串。

  2. 无论如何我只能从哈希中提取盐部分吗?我知道我可能不需要这样做,因为 crypt() 函数会在进行比较时在内部进行。但只是为了它。只是为了让我看到盐。对于 egs,请考虑此代码 -

    $pass = 'secret'; $salt = '$2y$07$usesomesillystringforsalt$'; echo crypt($pass, $salt);

    它的输出是$2y$07$usesomesillystringforex.u2VJUMLRWaJNuw0Hu2FvCEimdeYVO,我不确定盐和散列之间的边界。 'forex' 子字符串中的 'e' 是 salt 还是 hash 的一部分?如果我能提取其中的盐部分会容易得多。

  3. crypt() 手册也说

    ... Blowfish 使用盐散列如下:“$2a$”、“$2x$”或“$2y$”、两位数的成本参数、“$”和字母表中的 22 个字符“。 /0-9A-Za-z"....

    据此,我预计成本参数后面的 $ 符号后有 22 个字符。但是考虑一下这段代码 -

    $pass = 'secret'; $salt = '$2y$07$somesillystring$'; echo crypt($pass, $salt);

    其输出为$2y$07$somesillystring$$$$$$.O6JLPmGlDvy4BicGmkuBD.DN8OYiIoG。我的问题是为什么它在成本参数后的 $ 符号后面最多只能填充 21 个字符。我期望它最多可以填充 22 个字符。

【问题讨论】:

    标签: php crypt


    【解决方案1】:
    1. 一些 crypt() 算法用美元符号将盐与 crypt 分开。河豚没有。

    2. PHP 不提供仅提取盐的工具。您需要一个算法和盐位置/长度的关联数组。

    3. 我不确定为什么会有 21 和 22 的字符差异。会不会是 PHP 手册中的错误?尝试运行“man crypt”或转到http://linux.die.net/man/3/crypt

    【讨论】:

      【解决方案2】:

      我依稀记得在某处读过,仅使用了第 22 个字符的左 4 位/半字节。但是在运行以下 sn-p 之后,我看不到散列前后第 22 个字符的二进制表示之间的关系。 但第 22 个字符确实对结果有影响。

      $pass = 'secret';
      $salt = '$2y$07$usesomesillystringforsalt$';
      $hash = crypt($pass, $salt);
      
      var_dump(
          $hash,
          str_split($hash) // the 22th salt character 'e' is on index 28
      );
      
      function meow($char) {
          $hash = crypt('secret', '$2y$04$usesomesillystringfor' . $char);
          $substr = substr($hash, 28, 1);
      
          var_dump(
              $hash,
              $char,
              decbin(ord($char)),
              $substr,
              decbin(ord($substr)),
              '------------------------------'
          );
      }
      
      $alphabet = str_split('abcdefghijklmnopqrstuvwxyz');
      
      foreach($alphabet as $char) {
          meow($char);
      }
      

      自己看看:http://3v4l.org/qQmho

      【讨论】:

      • 尽管没有严格记录,但对于 PHP 5.5+,您必须有一个后缀 $(即使 5.4 - 5.4.37 的某些最新版本在 Ubuntu 上也无法运行)。好消息是在现有代码中添加$ 不会改变结果:3v4l.org/VA1dS