Каков наилучший способ генерации криптографически безопасной соли 32 байт в PHP, не зависящей от библиотек, редко включаемых в типичные установки PHP?
После некоторого googling я обнаружил, что mt_rand
не считается достаточно безопасным, но я не нашел предложения о замене. Одна статья предложила прочитать /dev/random
но не только это не будет работать на окнах; он также очень медленный.
Я хочу разумный баланс между безопасностью и скоростью (т. Е. Не должно занимать 20 секунд, чтобы генерировать 512 байт, как обычно /dev/random
)
Примечание .
mcrypt
устарел в PHP 7.1. Перейти к актуальному ответу .
Вы можете посмотреть документацию (и комментарии) для mcrypt_create_iv()
.
Это проще в PHP 7: просто используйте $salt = random_bytes($numberOfDesiredBytes);
для получения соли.
Во всяком случае, для чего вам нужна соль? Если это пароли, просто используйте password_hash()
и password_verify()
.
Примечание .
mcrypt
устарел в PHP 7.1. Перейти к актуальному ответу .
Вы можете использовать функцию mycrypt_create_iv()
, так как PHP Version 5.3 также использует случайный источник на сервере Windows (не только в Unix). Прежде чем использовать его, вы должны проверить, определен ли константа MCRYPT_DEV_URANDOM
.
mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
В отличие от случайного, урбанд не блокирует сервер, если доступной энтропии недостаточно. Поскольку соль паролей должна быть уникальной (не обязательно случайной), уранд, по-видимому, является хорошим выбором для меня.
uniqueid
не подходит для генерации случайной строки, поскольку она также microtime
на microtime
. Цикл ЦП, как правило, намного короче, чем microtime-tick, что может привести к возможному постоянству для данной переменной внутри циклов. Установка второго параметра «энтропия» в значение true,
uniqid('', true)
обеспечит повышенную случайность.
Чтобы получить случайную строку, которая хорошо совместима с большинством наборов символов, можно применить кодировку base64 к векторной функции mcrypt_create_iv
:
$length = 16; base64_encode(mcrypt_create_iv(ceil(0.75*$length), MCRYPT_DEV_URANDOM)) //> hlZuRJypdHFQPtI2oSFrgA== strlen(base64_encode(mcrypt_create_iv(ceil(0.75*$length), MCRYPT_DEV_URANDOM))) //> 16
Уменьшение символа-алфавита до 2 ^ 6Bit увеличивает размер, который учитывается выше.
Прочтите /dev/urandom
или используйте openssl_random_pseudo_bytes()
.
uniqid () должно быть хорошо для этой цели.
Я думаю, что microtime()
достаточно.
Странно, но я все еще получаю downvotes для этого ответа.
Хотя единственное объяснение, которое я получаю, это то, что микро-время предсказуемо.
Это звучит странно для меня, поскольку соль всегда воспринимается как открыто известная, так что для прогнозирования вообще нет смысла.