Я хотел бы создать хэш-адрес сайта для использования в качестве соли при создании жетонов для извлечения пароля. Я подпрыгивал вокруг stackoverflow, пытаясь понять, как это сделать.
Вот процесс перезагрузки:
Когда пользователь запрашивает адрес сброса пароля, код генерирует токен извлечения:
$token = hash_hmac('sha256', $reset_hash* , $site_hash)
* $ reset_hash – это хэш, созданный с использованием функции hpassPassword (), сохраненной в пользовательской таблице.
Затем я отправляю токен в URL-адрес на адрес электронной почты пользователей. Они щелкают перед временем токена через час. Я согласен с их представлением с маркером вызова, созданным на стороне сервера. Если он соответствует, то они вынуждены выбрать новый пароль, а затем войти в систему.
Я хотел бы знать лучший способ генерации $ site_key. Я думаю использовать другой хэш HMAC, который засевается случайными числами:
$site_key = hash_hmac('sha256', MCRYPT_DEV_RANDOM, MCRYPT_DEV_RANDOM);
Это создает что-то вроде этого:
98bb403abbe62f5552f03494126a732c3be69b41401673b08cbfefa46d9e8999
Будет ли это случайным образом использоваться для этой цели? Могу ли я это преувеличивать или приближаться к нему неправильно?
Я был вдохновлен использовать HMAC этим ответом
EDIT: Я стараюсь избегать «секретного вопроса», на который настаивают некоторые из моих коллег, поэтому я хотел бы, чтобы ссылка сброса обеспечила один шаг к сбросу пароля. Поэтому я обеспокоен тем, что этот процесс достаточно безопасен для защиты системы, содержащей конфиденциальную информацию.
RESOLVED, на данный момент: я собираюсь пойти с nonce, как описано The Rook как токен сброса. Спасибо всем за комментарии и отзывы.
Прежде всего, вы не говорите о соли. Вы говорите о криптографическом Nonce , и когда вы соедините пароль, вы должны использовать Cryptographic Nonce. В случае сброса паролей это должно быть случайное число, которое хранится в базе данных. Не выгодно иметь «соль сайта».
В первую очередь мне не нравится uniqid (), потому что это временный тяжелый расчет, а время – очень слабое семя . rand () vs mt_rand () , spoiler: rand () – полная дерьмо.
В веб-приложении хорошим источником безопасных секретов является неблокирующий доступ к энтропийному пулу, например /dev/urandom
. Начиная с PHP 5.3, приложения PHP могут использовать openssl_random_pseudo_bytes()
, а библиотека Openssl выберет лучший источник энтропии на основе вашей операционной системы, в Linux это означает, что приложение будет использовать /dev/urandom
. Этот код от Скотта довольно хорош :
function crypto_rand_secure($min, $max) { $range = $max - $min; if ($range < 0) return $min; // not so random... $log = log($range, 2); $bytes = (int) ($log / 8) + 1; // length in bytes $bits = (int) $log + 1; // length in bits $filter = (int) (1 << $bits) - 1; // set all lower bits to 1 do { $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes))); $rnd = $rnd & $filter; // discard irrelevant bits } while ($rnd >= $range); return $min + $rnd; } function getToken($length=32){ $token = ""; $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz"; $codeAlphabet.= "0123456789"; for($i=0;$i<$length;$i++){ $token .= $codeAlphabet[crypto_rand_secure(0,strlen($codeAlphabet))]; } return $token; }