生成用于创建密码检索令牌的随机"站点盐"的好方法是什么?

Tod*_*erg 14 php security passwords hash password-protection

我想创建一个站点范围的哈希,用作创建密码检索令牌的salt.我一直在使用stackoverflow进行反复尝试,以了解最佳方法.

这是重置过程:

当用户请求密码重置电子邮件时,代码会生成检索令牌:

$token = hash_hmac('sha256', $reset_hash* , $site_hash)
Run Code Online (Sandbox Code Playgroud)

*$ reset_hash是使用phpass HashPassword()函数创建的哈希,保存在用户表中.

然后,我将URL中的令牌发送到用户的电子邮件地址.他们在令牌超时前一小时点击.我将他们的提交与服务器端生成的挑战令牌相匹配.如果匹配,则强制他们选择新密码,然后登录.

我想知道生成$ site_key的最佳方法.我正在考虑使用由随机数播种的另一个HMAC哈希:

$site_key = hash_hmac('sha256', MCRYPT_DEV_RANDOM, MCRYPT_DEV_RANDOM);
Run Code Online (Sandbox Code Playgroud)

这产生了这样的东西:

98bb403abbe62f5552f03494126a732c3be69b41401673b08cbfefa46d9e8999
Run Code Online (Sandbox Code Playgroud)

这是否适合用于此目的?我是在过度复杂,还是以错误的方式接近它?

我的灵感来自于这个答案使用HMAC

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

已解决,现在:我将使用The Rook描述的nonce作为重置令牌.感谢大家的意见和反馈.

roo*_*ook 23

首先,你不要谈论盐.你在谈论一个加密的Nonce,当你加密密码时,你应该使用一个Cryptographic Nonce.在重置密码的情况下,它应该是存储在数据库中的随机数.具有"现场盐"是不利的.

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

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

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;
}
Run Code Online (Sandbox Code Playgroud)

  • @Todd Holmberg获取一个随机数的哈希值不会使它更随机,只需使用此值. (2认同)
  • @Gumbo,@ TheRook在[base64_encode()](http://us2.php.net/manual/en/function.base64-encode.php)页面的评论中找到了这个:`$ output = strtr(base64_encode($输入),'+/=',' - _,')` (2认同)