md5(uniqid)对随机唯一令牌有意义吗?

2022-08-30 13:36:51

我想创建一个令牌生成器,该生成器生成用户无法猜测并且仍然唯一的令牌(用于密码重置和确认代码)。

我经常看到这个代码;这有意义吗?

md5(uniqid(rand(), true));

根据评论产生uniqid($prefix, $moreEntopy = true)

前 8 个十六进制字符 = Unixtime,最后 5 个十六进制字符 = 微秒。

我不知道-参数是如何处理的。$prefix

因此,如果您不将$moreEntopy标志设置为 true,则会给出可预测的结果。


问:但是,如果我们使用uniqid$moreEntopy,那么用md5散列它能给我们带来什么好处?它是否比以下情况更好:

md5(mt_rand())

编辑1:我将此令牌存储在具有唯一索引的数据库列中,因此我将检测列。可能感兴趣/


答案 1

rand() 是一种安全隐患,永远不应该用于生成安全令牌:rand() vs mt_rand() (查看“静态”图像)。但是这些生成随机数的方法在加密上都是安全的。要生成安全安全隔离,应用程序需要访问由平台、操作系统或硬件模块提供的 CSPRNG

在 Web 应用程序中,安全机密的一个很好的来源是对熵池(如 .)的无阻塞访问。从 PHP 5.3 开始,PHP 应用程序可以使用 ,而 Openssl 库将根据您的操作系统选择最佳的熵源,在 Linux 下,这意味着应用程序将使用 。Scott 的这个代码片段非常好/dev/urandomopenssl_random_pseudo_bytes()/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;
}

答案 2

这是我在几个月前发现的另一个问题的副本。这是这个问题的链接和我的答案:https://stackoverflow.com/a/13733588/1698153

我不同意接受的答案。根据PHP自己的网站"[uniqid] does not generate cryptographically secure tokens, in fact without being passed any additional parameters the return value is little different from microtime(). If you need to generate cryptographically secure tokens use openssl_random_pseudo_bytes()."

我不认为答案比这更清楚,是不安全的。uniqid


推荐