忘记密码方案 - 如何创建令牌

时间:2011-10-12 11:40:09

标签: security token

我想在Web应用程序中实现一个被遗忘的密码方案。系统将向用户发送一封电子邮件,其中包含用户可以点击的唯一URL,以允许他们重置密码。在线有很多指导。以下是一个很好的方法,建议如何实现这一点。 Best way of doing code for "Forgotten Password"

我完全不了解的部分是令牌生成。这是什么意思??这只是一个针对用户存储在服务器上的guid(或随机字符串)(可能在用户db表中)。 guid也在url中发送(作为查询字符串),以便当请求到达Web服务器时,它可以查看guid并查找要重置的用户帐户。它还有更多吗?许多人谈论令牌过期。我可以在guid之前存储一个到期时间,之后无法完成帐户重置。

有些人建议使用CSRF令牌,但我无法理解这在这种情况下是如何工作的。

任何指导都将非常感谢...... :)

2 个答案:

答案 0 :(得分:4)

存储随机生成的(至少)128位服务器端的令牌,以及用户名和到期日期,将完全正常工作。

实现相同的另一种方法(无需存储任何服务器端)是计算

hash = hash(secret + user name + expiration date)

其中+表示概念,hash()是加密安全散列函数(如SHA2),secret是(至少)128位的字符串,仅 you 已知,并将其发送给用户:

user name + expiration date + hash

这两种方法都实现了相同的安全性,但请注意 - 在令牌过期之前 - 用户可以多次更改密码。

在第一种情况下,请确保随机创建token(例如,如果您使用的话,请使用/dev/random)。第二个问题与secret相同。但secret是静态的(为每个请求新生成)。

答案 1 :(得分:0)

我使用这段代码生成我的令牌:

/**
 * generates a random token, uses base64: 0-9a-zA-Z/+
 * @param int [optional] $length length of token, default 24 (144 Bit)
 * @return string token
 */
function generateToken($length = 24) {
        if(function_exists('openssl_random_pseudo_bytes')) {
            $token = base64_encode(openssl_random_pseudo_bytes($length, $strong));
            if($strong == TRUE)
                return substr($token, 0, $length); //base64 is about 33% longer, so we need to truncate the result
        }

        //fallback to mt_rand if php < 5.3 or no openssl available
        $characters = '0123456789';
        $characters .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/+'; 
        $charactersLength = strlen($characters)-1;
        $token = '';

        //select some random characters
        for ($i = 0; $i < $length; $i++) {
            $token .= $characters[mt_rand(0, $charactersLength)];
        }        

        return $token;
}

来源:http://www.php.net/manual/en/function.openssl-random-pseudo-bytes.php#96812