PHP: лучший способ создать и сохранить токен для подтверждения по электронной почте (3 варианта)

1

Я хотел бы создать токен в 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)?

Большое спасибо заранее, Майк

  • 0
    @ meh: Большое спасибо за это. Вы также можете сообщить мне, какой тип данных мне следует использовать для хранения этого в БД? Если вы хотите опубликовать это как ответ, я приму это.
  • 0
    Кстати, mcrypt_create_iv(16, MCRYPT_DEV_URANDOM); дает вам 16 байтов (128 бит).
Теги:
encryption
token

1 ответ

5
Лучший ответ

Не используйте uniqid() как случайное значение в любом критическом для безопасности коде. Это включает сброс пароля - злоумышленник может предсказать значение uniqid(), позволяя им угадать маркер безопасности и сбросить пароль любого пользователя в вашей системе.

Вместо этого используйте bin2hex(openssl_random_pseudo_bytes(…)) (как видно из вашего вопроса), чтобы создать безопасный случайный токен. Руководство PHP специально рекомендует эту функцию для этой цели в сноске к записи на uniqid():

Эта функция [то есть uniqid() ] не генерирует криптографически защищенные маркеры, фактически без каких-либо дополнительных параметров возвращаемое значение мало отличается от microtime(). Если вам нужно создать криптографически безопасные токены, используйте openssl_random_pseudo_bytes().

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


Для максимальной безопасности вы можете сделать еще один шаг. Вместо того, чтобы хранить токен в базе данных, храните хеш маркера (например, sha1($token)) в базе данных, а затем сравните хэш значения, представленного пользователем с сохраненным хэшем. По сути, относитесь к нему как к паролю! Этот дополнительный шаг будет препятствовать злоумышленнику, который имеет возможность читать вашу базу данных, но не писать ему, получать контроль над учетной записью пользователя, читая маркер "забытого пароля" из базы данных.

  • 0
    Большое спасибо - это действительно полезно! Так что для токена я должен использовать $ token = bin2hex (openssl_random_pseudo_bytes (16)); как в моем ответе или я должен что-то там добавить или изменить?
  • 0
    Также мне нравится идея хранить хэш токена. Какой тип данных мне нужно использовать (в MySQL) при хранении так, как вы предлагали?
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню