产生随机“位点盐”的好方法是什么?用于创建密码检索令牌?
我想创建一个站点范围的哈希,在创建密码检索令牌时用作盐。我一直在 stackoverflow 上徘徊,试图了解做到这一点的最佳方法。
重置过程如下:
当用户请求密码重置电子邮件时,代码会生成检索令牌:
$token = hash_hmac('sha256', $reset_hash* , $site_hash)
*$reset_hash 是使用 phpass HashPassword() 函数创建的哈希值,保存在用户表中。
然后,我将 URL 中的令牌发送到用户的电子邮件地址。他们在令牌在一小时内超时之前单击。我将他们的提交与服务器端生成的挑战令牌进行匹配。如果匹配,则他们被迫选择新密码,然后登录。
我想知道生成 $site_key 的最佳方法。我正在考虑使用另一个由随机数播种的 HMAC 哈希值:
$site_key = hash_hmac('sha256', MCRYPT_DEV_RANDOM, MCRYPT_DEV_RANDOM);
这会产生如下内容:
98bb403abbe62f5552f03494126a732c3be69b41401673b08cbfefa46d9e8999
这是否是用于此目的的适当随机数?我是否使这个问题过于复杂化,或者以错误的方式处理它?
<强>编辑:我试图避免一些同事催促的“秘密问题”步骤,因此我希望重置链接提供重置密码的单个步骤。因此,我担心这个过程是否足够安全以保护包含敏感信息的系统。
目前已解决:我将使用 The Rook 所描述的随机数作为重置令牌。感谢大家的评论和反馈。
I would like to create a site-wide hash to be used as salt in creating password retrieval tokens. I have been bouncing around stackoverflow trying to get a sense of the best way to do this.
Here's the reset process:
When a user requests a password reset email the code generates a retrieval token:
$token = hash_hmac('sha256', $reset_hash* , $site_hash)
*$reset_hash is a hash created using phpass HashPassword() function, saved in the user table.
I then send the token in a URL to the users email address. They click before the token times out in an hour. I match their submission with the a challenge token generated server-side. If it matches, then they are forced to choose a new password, and then login.
I would like to know the best way to generate the $site_key. I am thinking of using another HMAC hash that is seeded by random numbers:
$site_key = hash_hmac('sha256', MCRYPT_DEV_RANDOM, MCRYPT_DEV_RANDOM);
This produces something like this:
98bb403abbe62f5552f03494126a732c3be69b41401673b08cbfefa46d9e8999
Will this be a suitably random to be used for this purpose? Am I overcomplicating this, or approaching it the wrong way?
I was inspired to use HMAC by this answer
EDIT: I am trying to avoid a 'secret question' step urged by some of my coworkers, so I would like the reset link to provide a single step to resetting the password. Therefore, my concern is that this process be secure enough to safeguard a system containing sensitive information.
RESOLVED, for now: I am going to go with a nonce as described by The Rook as the reset token. Thanks everyone for the comments and feedback.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,你不是在谈论盐。您正在谈论加密随机数,当您对密码加盐时,您应该使用加密随机数。在重置密码的情况下,它应该是存储在数据库中的随机数。具有“位点盐”并不是有利的。
首先,我不喜欢 uniqid()因为这是一个时间繁重的计算,并且时间是一个非常弱的种子。 rand() 与 mt_rand(),剧透:rand() 完全是垃圾。
在 Web 应用程序中,安全秘密的良好来源是对熵池(例如
/dev/urandom
)的非阻塞访问。从 PHP 5.3 开始,PHP 应用程序可以使用openssl_random_pseudo_bytes()
,Openssl 库将根据您的操作系统选择最佳的熵源,在 Linux 下这意味着应用程序将使用/dev/ urandom
。 Scott 的这个代码片段相当不错:To start with, your not talking about a salt. You're talking about a Cryptographic Nonce, and when you salt a password you should use a Cryptographic Nonce. In the case of resetting passwords, it should be a random number that is stored in the database. It is not advantageous to have have a "site salt".
First and foremost I don't like uniqid() because it's a time heavy calculation and time is a very weak seed. rand() vs mt_rand(), spoiler: rand() is total crap.
In a web application a good source for secure secrets is non-blocking access to an entropy pool such as
/dev/urandom
. As of PHP 5.3, PHP applications can useopenssl_random_pseudo_bytes()
, and the Openssl library will choose the best entropy source based on your operating system, under Linux this means the application will use/dev/urandom
. This code snip from Scott is pretty good: