Как создать случайную длинную соль для использования в хешировании?

Каким образом в PHP можно создать случайную соль переменной длины для использования в хешировании? Скажем, я хочу сделать 16-значную длинную соль - как бы я это сделал?

Ответы

Ответ 1

edit: расширение mcrypt устарело. Для новых проектов взгляните на
random_bytes (int $length)
и sodium (с расширением php 7.2 core-).


Если доступно расширение mcrypt, вы можете просто использовать mcrypt_create_iv (размер, источник), чтобы создать соль.

$iv = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
var_dump($iv);

Поскольку каждый байт "строки" может находиться в диапазоне от 0 до 255, вам нужна двоично-безопасная функция для сохранения/извлечения.

Ответ 2

в зависимости от вашей ОС, что-то вроде:

$fh=fopen('/dev/urandom','rb');
$salt=fgets($fh,16);
fclose($fh);

Читайте о поведении случайных и урбандов.

В то время как другие правильно указали, что есть некоторые проблемы с md5 и повторным хешированием, для паролей (т.е. относительно коротких строк) атаки с грубой силой занимают одинаковое количество времени, независимо от того, насколько сложным является алгоритм хэширования.

С.

Ответ 3

Вот я нашел функцию для генерации случайной строки:

/* random string */
function rand_string( $length ) {
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  
    $size = strlen( $chars );
    for( $i = 0; $i < $length; $i++ ) {
        $str .= $chars[ rand( 0, $size - 1 ) ];
    }
    return $str;
}

Ответ 4

Есть две предпосылки для хорошей соли: она должна быть длинной, и она должна быть случайной. Есть много способов сделать это. Например, вы можете использовать комбинацию microtime и rand, но вы можете перейти на еще большую длину, чтобы убедиться, что ваша соль уникальна.

В то время как вероятность столкновения является пренебрежимой, имейте в виду, что хеширование вашей соли с помощью MD5 или других алгоритмов, подверженных столкновениям, уменьшит вероятность того, что ваша соль уникальна без причины.

EDIT: замените rand() на mt_rand(). Как отметил Майкл, это лучше, чем rand.