Генерация соли в PHP - PullRequest
       65

Генерация соли в PHP

12 голосов
/ 25 марта 2010

Каков наилучший способ создания криптографически безопасной 32-байтовой соли в PHP без зависимости от библиотек, редко включаемых в типичные установки PHP?

После некоторого поиска в Google я обнаружил, что mt_rand не считается достаточно безопасным, но я не нашел предложения по замене. Одна статья предложила прочитать из /dev/random, но не только это не будет работать на Windows; это также очень медленно.

Мне нужен разумный баланс между безопасностью и скоростью (т. Е. Генерация 512 байт не должна занимать 20 секунд, как обычно делает /dev/random)

Ответы [ 7 ]

14 голосов
/ 09 декабря 2015

Это проще в PHP 7: Просто используйте $salt = random_bytes($numberOfDesiredBytes); для генерации соли.

Зачем тебе соль? Если это пароли, просто используйте password_hash() и password_verify().

7 голосов
/ 24 августа 2012

Примечание : mcrypt устарело в PHP 7.1. Перейти к последнему ответу .

Вы можете использовать функцию mycrypt_create_iv(), поскольку PHP версии 5.3 также использует случайный источник на сервере Windows (не только в Unix). Перед его использованием следует проверить, определена ли постоянная MCRYPT_DEV_URANDOM.

mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);

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

7 голосов
/ 25 марта 2010

Примечание : mcrypt устарело в PHP 7.1. Перейти к последнему ответу .

Возможно, вы захотите взглянуть на документацию (и комментарии) для mcrypt_create_iv().

2 голосов
/ 19 сентября 2013

uniqueid не очень подходит для генерации случайной строки, так как она также основана на microtime. Цикл ЦП обычно намного короче, чем микротим, что может привести к возможному постоянству для данной переменной внутри циклов. Установка второго параметра "энтропия" в значение 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 ^ 6Бит увеличивает размер, который учитывается выше.

0 голосов
/ 03 августа 2012

Чтение из /dev/urandom или использование openssl_random_pseudo_bytes().

0 голосов
/ 25 марта 2010

uniqid () должно подойти для этой цели.

0 голосов
/ 25 марта 2010

Я думаю, что microtime() достаточно.

Странно, но я все еще получаю отрицательные отзывы за этот ответ.

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

...