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

2022-01-22 00:00:00 random hash passwords security php

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

I want to create a token generator that generates tokens that cannot be guessed by the user and that are still unique (to be used for password resets and confirmation codes).

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

I often see this code; does it make sense?

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

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

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

first 8 hex chars = Unixtime, last 5 hex chars = microseconds.

不知道$prefix-参数是怎么处理的..

I don't know how the $prefix-parameter is handled..

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

So if you don't set the $moreEntopy flag to true, it gives a predictable outcome.

问题: 但是,如果我们将 uniqid$moreEntopy 一起使用,那么使用 md5 对其进行哈希处理能给我们带来什么?是否优于:

QUESTION: But if we use uniqid with $moreEntopy, what does hashing it with md5 buy us? Is it better than:

md5(mt_rand())

edit1:我会将此标记存储在具有唯一索引的数据库列中,因此我将检测列.可能感兴趣/

edit1: I will store this token in an database column with a unique index, so I will detect columns. Might be of interest/

推荐答案

rand() 存在安全隐患,绝不能用于生成安全令牌:rand() 与 mt_rand() (查看静态"图像).但是这些生成随机数的方法都不是密码安全的.要生成安全证书,应用程序需要访问由平台、操作系统或硬件模块.

rand() is a security hazard and should never be used to generate a security token: rand() vs mt_rand() (Look at the "static" like images). But neither of these methods of generating random numbers is cryptographically secure. To generate secure secerts an application will needs to access a CSPRNG provided by the platform, operating system or hardware module.

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

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 use openssl_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:

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;
}

相关文章