我想在PHP中创建一个令牌,可以用作确认电子邮件,作为密码重置请求的一部分。
在线搜索时,我在post遇到了以下内容:
$token = md5(uniqid(mt_rand(), true));
有人可以告诉我这里是否应该优先选择,并告诉我这里有什么区别?
$token = bin2hex(openssl_random_pseudo_bytes(16));
OR
$token = bin2hex(mcrypt_create_iv(128, MCRYPT_DEV_RANDOM));
另外,你能告诉我应该使用哪种数据类型来存储这个(使用MySQL)?
非常感谢, 麦克
答案 0 :(得分:5)
不要在任何安全关键代码中使用uniqid()
作为随机值。这包括密码重置 - 攻击者可能能够预测uniqid()
的值,允许他们猜测安全令牌并重置系统上任何用户的密码。
相反,请使用bin2hex(openssl_random_pseudo_bytes(…))
(如您的问题所示)来创建安全的随机令牌。 PHP手册专门为uniqid()
上的条目的脚注提供了此功能:
此函数[即
uniqid()
]不会生成加密安全令牌,事实上,如果没有传递任何其他参数,则返回值与microtime()略有不同。如果您需要生成加密安全令牌,请使用openssl_random_pseudo_bytes()
。
由于bin2hex()
是可打印字符串,您可以使用任何字符串类型将其存储在数据库中。 <{1}}应该是您的默认选择,这非常合适。
为了最大限度地提高安全性,您可能需要再执行一个步骤。不是将令牌存储在数据库中,而是将令牌的散列(例如,VARCHAR
)存储在数据库中,然后将用户呈现的值的散列与存储的散列进行比较。从本质上讲,将其视为密码!此额外步骤将阻止具有读取数据库但不能写入数据库的攻击者通过从数据库中读取其“忘记密码”令牌来获取对用户帐户的控制权。