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