【问题标题】:Is hash() randomization considered cryptographically strong?hash() 随机化是否被认为具有加密强度?
【发布时间】:2014-06-16 23:58:13
【问题描述】:

CPython 3.3 开始,默认启用哈希随机化。在以前的版本中,可以通过指定-R command-line option 或将PYTHONHASHSEED environment variable 设置为random 来打开它。

引用documentation

默认情况下,__hash__() 的 str、bytes 和 datetime 值 对象用不可预测的随机值“加盐”。虽然他们 在单个 Python 进程中保持不变,它们不是 在 Python 的重复调用之间可预测。

这是否意味着生成的值在密码学上会很强大?

【问题讨论】:

  • cryptographically secure (at least for one session) 是什么意思?
  • 另外,整数的hash 只是那个整数。这在解释器调用之间不会改变。

标签: python python-3.x hash python-3.3 random-seed


【解决方案1】:

Py 3.4之前,Python使用了一个FNV的变体,这在没有加密地保护。不幸的是,只需为Python等弱散列函数添加一个随机值,尝试了任何真正的安全性。易于生成具有相同FNV哈希的字符串,即使在随机化的存在下,由于底层散列算法的弱点。

注意,即使种子是完全随机的,也没有泄露给客户端,这是真的。

要考虑为什么,想象一个非常弱的哈希函数 - 只需在字符串中添加所有字符。在这种情况下,如果将随机值添加到开头,则任何单个字符串的哈希将是随机的。但是,如果两个字符串的字符与相同的值总和,则它们将散列到相同的值,无论随机种子如何。因此,随机种子不提供任何抗碰撞性。 Python实际上并不是那么糟糕,但它也没有多得多。

在3.4中,Python将默认算法切换到Siphash,这被加密保护碰撞DOS攻击所信仰。不幸的是,任何使用2.x的人都没有运气。

【讨论】:

    【解决方案2】:

    在 Python 3.3 中,哈希种子的密码强度不高;它是在启动时使用以下伪随机生成器生成的:

    /* Fill buffer with pseudo-random bytes generated by a linear congruent
       generator (LCG):
    
           x(n+1) = (x(n) * 214013 + 2531011) % 2^32
    
       Use bits 23..16 of x(n) to generate a byte. */
    static void
    lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
    {
        size_t index;
        unsigned int x;
    
        x = x0;
        for (index=0; index < size; index++) {
            x *= 214013;
            x += 2531011;
            /* modulo 2 ^ (8 * sizeof(int)) */
            buffer[index] = (x >> 16) & 0xff;
        }
    }
    

    不是cryptographically strong

    还有 other problems with the hash seeding 仍然可以强制碰撞。

    Python 3.4 addressed these issues 默认引入more secure hashing algorithm,并使其可插拔。

    如果您在程序中需要加密强随机数,请改用 random.SystemRandom()os.urandom()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      • 1970-01-01
      • 2014-03-08
      • 2023-03-15
      • 2015-08-23
      相关资源
      最近更新 更多