Ответ 1
Примечание:
mcrypt
устарело в PHP 7.1. Переход к актуальному ответу.
Возможно, вы захотите ознакомиться с документацией (и комментариями) для mcrypt_create_iv()
.
Какой лучший способ создать криптографически безопасную соль 32 байта в PHP, не зависимо от библиотек, редко включаемых в типичные установки PHP?
После некоторых поисковых запросов я обнаружил, что 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-tick, что может привести к возможному постоянству для данной переменной внутри циклов.
Установка второго параметра "энтропия" в значение true,
uniqid('', true)
обеспечит повышенную случайность.
Чтобы получить случайную строку, которая хорошо совместима с большинством наборов символов, можно применить кодировку base64 к векторной функции инициализации mcrypt 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 для этого ответа.
Хотя единственное объяснение, которое я получаю, - это то, что микро-время предсказуемо. Это звучит странно для меня, поскольку соль всегда воспринимается как открыто известная, поэтому использовать предсказание вообще не нужно.