PHP:为确认电子邮件创建和存储令牌的最佳方式(3 个选项)

PHP: Best way to create and store token for confirmation email (3 options)

我想在 PHP 中创建一个令牌,作为密码重置请求的一部分,可用于确认电子邮件。

在网上搜索此内容时,我在 post 此处找到了以下内容:

$token = md5(uniqid(mt_rand(), true));

有人可以告诉我与下面的相比,这里是否更受欢迎,让我知道这里有什么区别?

$token = bin2hex(openssl_random_pseudo_bytes(16));

$token = bin2hex(mcrypt_create_iv(128, MCRYPT_DEV_RANDOM));

另外,你能告诉我应该使用哪种数据类型在数据库中存储这个(使用MySQL)吗?

非常感谢, 麦克

不要在任何安全关键代码中使用 uniqid() 作为随机值。这包括密码重置 — 攻击者可能能够预测 uniqid() 的值,从而允许他们猜测安全令牌并重置您系统上任何用户的密码。

相反,使用 bin2hex(openssl_random_pseudo_bytes(…))(如您的问题所示)创建安全的随机令牌。 PHP 手册在 uniqid():

条目的脚注中特别推荐此功能

This function [that is, uniqid()] does not generate cryptographically secure tokens, in fact without being passed any additional parameters the return value is little different from microtime(). If you need to generate cryptographically secure tokens use openssl_random_pseudo_bytes().

由于 bin2hex() 的结果是一个可打印的字符串,您可以使用任何字符串类型将其存储在数据库中。 VARCHAR 应该是您在这里的默认选择,它非常合适。


为了获得最大的安全性,您可能需要再采取一个步骤。不是将令牌存储在数据库中,而是将令牌的散列(例如 sha1($token))存储在数据库中,然后将用户提供的值的散列与存储的散列进行比较。本质上,将其视为密码!这个额外的步骤将阻止能够读取您的数据库但不能写入它的攻击者通过从数据库读取他们的 "forgot password" 令牌来控制用户帐户。