Считается ли рандомизация hash() криптографически сильной?

Начиная с CPython 3.3 рандомизация хэшей включена дефолт. В предыдущих версиях его можно было включить, указав -R параметр командной строки< /a> или задав для PYTHONHASHSEEDпеременную среды значение random.

Со ссылкой на документацию:

По умолчанию значения __hash__() объектов str, bytes и datetime «приправлены» непредсказуемым случайным значением. Хотя они остаются постоянными в пределах отдельного процесса Python, они непредсказуемы между повторными вызовами Python.

Означает ли это, что сгенерированное значение будет криптографически стойким?


person vaultah    schedule 30.04.2014    source источник
comment
Что вы имеете в виду под cryptographically secure (at least for one session)?   -  person thefourtheye    schedule 30.04.2014
comment
Кроме того, hash целого числа является только этим целым числом. Это не изменится между вызовами интерпретатора.   -  person thefourtheye    schedule 30.04.2014


Ответы (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;
    }
}

который не является криптографически стойким.

Существуют также другие проблемы с хеш-заполнением, из-за которых по-прежнему возможны коллизии.

Python 3.4 решил эти проблемы, добавив более безопасный алгоритм хеширования по умолчанию и сделал его подключаемым.

Если вам нужны криптографически стойкие случайные числа в вашей программе, используйте random.SystemRandom() или вместо этого os.urandom().

person Martijn Pieters    schedule 30.04.2014

До версии 3.4 Python использовал вариант FNV, который не является криптографически безопасным. К сожалению, простое добавление случайного значения к слабой хэш-функции, как это пробовал Python, не обеспечивает реальной безопасности. Легко сгенерировать строки, которые будут иметь один и тот же хэш FNV, даже при наличии рандомизации, благодаря слабости базового алгоритма хеширования.

Обратите внимание, что это верно, даже если начальное значение совершенно случайное и не просочилось к клиенту.

Чтобы понять, почему, представьте себе очень слабую хеш-функцию — простое сложение всех символов в строке. В этом случае, если вы добавите в начало случайное значение, то хэш любой отдельной строки будет случайным. Однако, если в двух строках есть символы, сумма которых дает одно и то же значение, то они будут хешироваться до одного и того же значения, независимо от того, что является случайным начальным числом. Следовательно, случайное начальное число не обеспечивает никакого сопротивления столкновениям. То, что на самом деле сделал Python, не так уж плохо, но и не намного лучше.

В версии 3.4 Python переключил алгоритм по умолчанию на SipHash, который, как считается, криптографически защищен от DOS-атак с коллизиями. К сожалению, любому, кто использует 2.x, совершенно не повезло.

person Antimony    schedule 10.02.2017