hash()随机化是否被认为是加密强大的?

时间:2014-04-30 15:16:30

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

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

引用documentation

  

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

这是否意味着生成的值将加密强大?

2 个答案:

答案 0 :(得分:6)

在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()

答案 1 :(得分:1)

在3.4之前,Python使用了FNV的变体,它不具有加密安全性。不幸的是,简单地将一个随机值添加到像Python这样的弱哈希函数中并没有提供任何真正的安全性。由于底层哈希算法的弱点,即使存在随机化,也很容易生成具有相同FNV哈希的字符串。

请注意,即使种子完全随机且未泄露给客户,也是如此。

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

在3.4中,Python将默认算法切换为SipHash,这是通过加密安全抵御碰撞DOS攻击而获得的。不幸的是,使用2.x的任何人都完全没有运气。