Как PHP-пароль генерирует соль?

Привет, как вы знаете, PHP недавно представил password_hash встроенный в последние версии. В документации говорится:

Если опустить, будет создана случайная соль, и будут использоваться стоимость по умолчанию.

Вопрос в том, какой метод он использует для добавления соли?

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

Соль создается случайным образом. Они должны быть статистически уникальными.

Чтобы узнать, как, посмотрите исходный код C.

В Windows он попытается использовать php_win32_get_random_bytes() для генерации соли:

 BYTE *iv_b = (BYTE *) buffer; if (php_win32_get_random_bytes(iv_b, raw_length) == SUCCESS) { buffer_valid = 1; } 

В Linux он попытается прочитать /dev/urandom для генерации соли:

 int fd, n; size_t read_bytes = 0; fd = open("/dev/urandom", O_RDONLY); if (fd >= 0) { while (read_bytes < raw_length) { n = read(fd, buffer + read_bytes, raw_length - read_bytes); if (n < 0) { break; } read_bytes += (size_t) n; } close(fd); } if (read_bytes >= raw_length) { buffer_valid = 1; } 

Затем, после этих двух, если буфер недействителен (не полный, он может быть частичным), он использует rand () для его заполнения. Обратите внимание, что на практике это никогда не должно происходить, это просто резерв:

 if (!buffer_valid) { for (i = 0; i < raw_length; i++) { buffer[i] ^= (char) (255.0 * php_rand(TSRMLS_C) / RAND_MAX); } } 

Теперь, если C не ваша чашка чая, в моей библиотеке совместимости реализованы те же логики и алгоритмы:

 $buffer = ''; $raw_length = (int) ($required_salt_len * 3 / 4 + 1); $buffer_valid = false; if (function_exists('mcrypt_create_iv')) { $buffer = mcrypt_create_iv($raw_length, MCRYPT_DEV_URANDOM); if ($buffer) { $buffer_valid = true; } } if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) { $buffer = openssl_random_pseudo_bytes($raw_length); if ($buffer) { $buffer_valid = true; } } if (!$buffer_valid && is_readable('/dev/urandom')) { $f = fopen('/dev/urandom', 'r'); $read = strlen($buffer); while ($read < $raw_length) { $buffer .= fread($f, $raw_length - $read); $read = strlen($buffer); } fclose($f); if ($read >= $raw_length) { $buffer_valid = true; } } if (!$buffer_valid || strlen($buffer) < $raw_length) { $bl = strlen($buffer); for ($i = 0; $i < $raw_length; $i++) { if ($i < $bl) { $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255)); } else { $buffer .= chr(mt_rand(0, 255)); } } } 

Единственное различие заключается в том, что версия PHP будет использовать mcrypt или openssl если они установлены …