15

我想创建一个站点范围的哈希,用作创建密码检索令牌的盐。我一直在 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

这将是一个适当的随机用于此目的吗?我是否过于复杂化,或者以错误的方式接近它?

这个答案启发了我使用HMAC

编辑:我试图避免我的一些同事敦促的“秘密问题”步骤,所以我希望重置链接提供一个重置密码的步骤。因此,我担心这个过程足够安全以保护包含敏感信息的系统。

目前已解决:我将使用 The Rook 所描述的随机数作为重置令牌。感谢大家的评论和反馈。

4

1 回答 1

24

首先,你不是在谈论盐。您在谈论Cryptographic Nonce,当您对密码进行加盐时,您应该使用 Cryptographic Nonce。在重置密码的情况下,它应该是存储在数据库中的随机数。拥有“站点盐”是不利的。

首先,我不喜欢uniqid()因为它是一个时间繁重的计算,而时间是一个非常弱的种子rand() vs mt_rand(),剧透: rand() 完全是废话。

在 Web 应用程序中,安全机密的良好来源是对熵池(例如/dev/urandom. 自 PHP 5.3 起,PHP 应用程序可以使用openssl_random_pseudo_bytes().Openssl 库将根据您的操作系统选择最佳熵源,在 Linux 下这意味着应用程序将使用/dev/urandom. Scott 的这段代码非常好:

function crypto_rand_secure($min, $max) {
        $range = $max - $min;
        if ($range < 0) return $min; // not so random...
        $log = log($range, 2);
        $bytes = (int) ($log / 8) + 1; // length in bytes
        $bits = (int) $log + 1; // length in bits
        $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
            $rnd = $rnd & $filter; // discard irrelevant bits
        } while ($rnd >= $range);
        return $min + $rnd;
}

function getToken($length=32){
    $token = "";
    $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
    $codeAlphabet.= "0123456789";
    for($i=0;$i<$length;$i++){
        $token .= $codeAlphabet[crypto_rand_secure(0,strlen($codeAlphabet))];
    }
    return $token;
}
于 2010-07-20T15:36:00.777 回答