【问题标题】:Understanding character replacement in salt function了解盐函数中的字符替换
【发布时间】:2014-08-12 01:50:00
【问题描述】:

我在网上找到了以下代码,想知道为什么在对 mcrypt_create_iv() 的返回值进行 base64 编码后,作者确实替换了所有 + 符号。

    $salt = mcrypt_create_iv(22, MCRYPT_DEV_URANDOM);
    $salt = base64_encode($salt);
    $salt = str_replace('+', '.', $salt); 

盐稍后被传递给 crypt() 以生成密码哈希。所以我的假设是,用. 替换所有+ 与crypt() 有关。

【问题讨论】:

  • 可能是因为使用 +< 这样的字符可能会对 PHP 解析它们的方式产生不利影响;我以前见过这种情况。
  • Fred,你能详细说明一下,举个例子吗?谢谢。
  • 这个$salt=sprintf('$2y$%02d$',$cost); 例如取自我的一个无效脚本,它会生成适当的盐。但是,使用$salt=sprintf('$2y$%02d$+',$cost); 会生成*0;这不好。有问题的脚本是从我自己使用的这个答案stackoverflow.com/a/13153865 借来的。我确定我还有另一个脚本可以用作示例,但这会花费我更多的时间来查找/测试。
  • 在示例中,盐是否作为查询字符串的一部分通过 http/s 传输? (这不应该这样做,顺便说一句,但是......)如果是这样,一些http客户端和服务器会将+解释为空格。这是非标准行为,特别是针对 Url 的 RFC,但确实会发生(例如在 Chrome 中)。
  • 作者看起来很困惑,因为他们想生成 22 个 Base64 字符,但指定的是 22 个字节而不是 16 个。

标签: php cryptography salt


【解决方案1】:

So my assumption is, the replacement of all + with . has to do with crypt().

是的,确实如此。

来自crypt 文档:

CRYPT_STD_DES - 基于 DES 的标准哈希,带有来自字母表 "./0-9A-Za-z" 的两个字符盐。在 salt 中使用无效字符会导致 crypt() 失败。

CRYPT_EXT_DES - 扩展的基于 DES 的散列。 “salt”是一个 9 字符的字符串,由一个下划线后跟 4 个字节的迭代计数和 4 个字节的 salt 组成。这些被编码为可打印字符,每个字符 6 位,最低有效字符在前。值 0 到 63 被编码为 "./0-9A-Za-z"。在 salt 中使用无效字符会导致 crypt() 失败。

所以盐必须在字母表中./0-9A-Za-z

【讨论】:

  • 谢谢。那么生成盐的功能一定是不够的,因为它没有替换 = 符号。
【解决方案2】:

没有更多上下文,我只能猜测,但我可以给你一个很可能的原因:

在许多设置中,密码哈希以method+iterations+salt+hash 之类的格式存储。 如果以这种方式存储,而不是将盐放在数据库中的单独列中,您需要一种方法将盐(和其他详细信息)从哈希中分离出来。如果它在+ 上分裂,那么盐中的额外加号会破坏该方法。

可以通过将散列、盐和方法存储在它们自己的列中,或者根据位置而不是特定字符进行拆分来避免这种情况。但是,无论如何,您似乎使用的方法都很好。替换一个特定字符不会对良好盐/哈希的成功产生有意义的影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2011-11-27
    • 2012-02-12
    • 2012-11-16
    • 1970-01-01
    • 2012-01-02
    • 2019-02-16
    相关资源
    最近更新 更多