Я хотел бы создать токен в PHP, который можно использовать для подтверждения электронной почты как часть запроса на сброс пароля.
При поиске этого онлайн я наткнулся на сообщение здесь, где нашел следующее:
$token = md5(uniqid(mt_rand(), true));
Может кто-нибудь сказать мне, если это будет предпочтительнее здесь по сравнению с ниже, и дайте мне знать, в чем отличия здесь?
$token = bin2hex(openssl_random_pseudo_bytes(16));
ИЛИ
$token = bin2hex(mcrypt_create_iv(128, MCRYPT_DEV_RANDOM));
Кроме того, можете ли вы сообщить мне, какой тип данных следует использовать для хранения этого в db (используя MySQL)?
Большое спасибо заранее, Майк
Не используйте uniqid()
как случайное значение в любом критическом для безопасности коде. Это включает сброс пароля - злоумышленник может предсказать значение uniqid()
, позволяя им угадать маркер безопасности и сбросить пароль любого пользователя в вашей системе.
Вместо этого используйте bin2hex(openssl_random_pseudo_bytes(…))
(как видно из вашего вопроса), чтобы создать безопасный случайный токен. Руководство PHP специально рекомендует эту функцию для этой цели в сноске к записи на uniqid()
:
Эта функция [то есть
uniqid()
] не генерирует криптографически защищенные маркеры, фактически без каких-либо дополнительных параметров возвращаемое значение мало отличается от microtime(). Если вам нужно создать криптографически безопасные токены, используйтеopenssl_random_pseudo_bytes()
.
В результате bin2hex()
является печатаемой строкой, вы можете сохранить ее в своей базе данных с использованием любого типа строки. VARCHAR
должен быть вашим выбором по умолчанию здесь, и он идеально подходит.
Для максимальной безопасности вы можете сделать еще один шаг. Вместо того, чтобы хранить токен в базе данных, храните хеш маркера (например, sha1($token)
) в базе данных, а затем сравните хэш значения, представленного пользователем с сохраненным хэшем. По сути, относитесь к нему как к паролю! Этот дополнительный шаг будет препятствовать злоумышленнику, который имеет возможность читать вашу базу данных, но не писать ему, получать контроль над учетной записью пользователя, читая маркер "забытого пароля" из базы данных.
mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
дает вам 16 байтов (128 бит).