Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php md5(uniqid)对随机唯一令牌有意义吗?_Php_Security_Hash_Random_Passwords - Fatal编程技术网

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

Php md5(uniqid)对随机唯一令牌有意义吗?,php,security,hash,random,passwords,Php,Security,Hash,Random,Passwords,我想创建一个令牌生成器,该生成器生成用户无法猜测且仍然唯一的令牌(用于密码重置和确认代码) 我经常看到这个代码;这有意义吗 md5(uniqid(rand(), true)); 根据uniqid($prefix,$morentopy=true) 前8个十六进制字符=Unixtime,最后5个十六进制字符=微秒 我不知道$prefix-参数是如何处理的 因此,如果您不将$morentopy标志设置为true,它将给出一个可预测的结果 问题:但是如果我们将uniqid与$morentopy一起使

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

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

md5(uniqid(rand(), true));
根据
uniqid($prefix,$morentopy=true)

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

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

因此,如果您不将$morentopy标志设置为true,它将给出一个可预测的结果


问题:但是如果我们将
uniqid
$morentopy
一起使用,那么用md5对其进行哈希运算会给我们带来什么好处?它是否比:


edit1:我将使用唯一索引将此令牌存储在数据库列中,因此我将检测列。可能会感兴趣/

MD5是一种用于生成依赖数据的ID的不错的算法。但如果您有多个具有相同比特流(内容)的项,您将生成两个类似的MD5“ID”

因此,如果您只是将其应用于
rand()
函数,该函数保证不会创建相同的数字两次,那么您是非常安全的


但为了更好地分发密钥,我个人会使用SHA1或SHAx等。。。但您仍然会遇到类似数据导致类似键的问题。

定义“唯一”。如果您的意思是两个令牌不能具有相同的值,那么散列是不够的——应该使用唯一性测试来支持它。提供具有唯一输入的哈希算法并不能保证输出的唯一性。

要回答您的问题,问题是您不能拥有一个保证随机且唯一的生成器,即,
md5(mt_rand())
可能导致重复。您需要的是“随机出现”唯一值。uniqid提供唯一的id,rand()附加一个随机数,使其更难猜测,md5屏蔽结果使其更难猜测。没有什么是无用的。我们只需要让它变得如此困难,以至于他们甚至不想尝试。

rand()是一种安全隐患,永远不应该被用来生成安全令牌:(看看类似“静态”的图像)。但这两种生成随机数的方法都不是加密安全的。要生成安全安全,应用程序需要访问平台、操作系统或硬件模块提供的

在web应用程序中,安全机密的一个好来源是对熵池(如
/dev/uradom
)的无阻塞访问。从PHP5.3开始,PHP应用程序可以使用
openssl\u random\u pseudo\u bytes()
,openssl库将根据您的操作系统选择最佳的熵源,在Linux下,这意味着应用程序将使用
/dev/uradom
。这:

函数加密和安全($min,$max){
$range=$max-$min;
如果($range<0)返回$min;//不太随机。。。
$log=log($range,2);
$bytes=(int)($log/8)+1;//字节长度
$bits=(int)$log+1;//以位为单位的长度
$filter=(int)(1=$range);
返回$min+$rnd;
}
函数getToken($length=32){
$token=“”;
$codeAlphabet=“abcdefghijklmnopqrstuvxyz”;
$codeAlphabet.=“abcdefghijklmnopqrstuvwxyz”;
$codeAlphabet.=“0123456789”;

因为($i=0;$i几年前我遇到了一个有趣的想法。
在数据库中存储两个哈希值,一个是用md5($a)生成的,另一个是用sha($a)生成的。然后检查这两个值是否正确。关键是,如果攻击者破坏了您的md5(),他在不久的将来就无法破坏您的md5和sha。

问题是:如何将该概念与问题所需的令牌生成一起使用?

这是我发现的另一个问题的副本,该问题在几个月前被提出。这里是该问题的链接和我的答案:

我不同意接受的答案。根据PHPs自己的网站
“[uniqid]不会生成加密安全令牌,事实上,在没有传递任何附加参数的情况下,返回值与microtime()几乎没有区别。如果需要生成加密安全令牌,请使用openssl_random_pseudo_bytes()


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

我知道这个问题很老,但它出现在谷歌上,所以

正如其他人所说,
rand()
mt\u rand()
uniqid()
不会保证您的唯一性……即使是
openssl\u random\u pseudo\u bytes()
也不应该使用,因为它使用

用于生成随机哈希(与md5相同)的内容是(在PHP7中介绍)。要生成与md5长度相同的哈希,请执行以下操作:

bin2hex(随机字节(16));


如果您使用的是PHP 5.x,则可以通过包含来获得此函数。

首先,此类过程的范围是创建一个键/散列/代码,该键/散列/代码对于给定的数据库是唯一的。不可能在给定时刻为整个世界创建唯一的。 也就是说,您应该使用自定义字母表创建一个简单可见的字符串,并根据数据库(表)检查创建的代码。 如果该字符串是唯一的,则对其应用
md5()
,任何人或任何脚本都无法猜到。 我知道,如果你深入研究密码生成的理论,你可以找到很多关于这种代码生成的解释,但是当你把它投入实际使用时,其实并没有那么复杂

下面是我用来生成一个简单的10位唯一代码的代码

$alphabet = "aA1!bB2@cC3#dD5%eE6^fF7&gG8*hH9(iI0)jJ4-kK=+lL[mM]nN{oO}pP\qQ/rR,sS.tT?uUvV>xX~yY|zZ`wW$";
$code = '';
$alplhaLenght = strlen($alphabet )-1;
for ($i = 1; $i <= 10; $i++) {
    $n = rand(1, $alplhaLenght );
    $code .= $alphabet [$n];
}
$alphabet=“aA1!bB2@cC3#dD5%eE6^fF7&gG8*hH9(iI0)jJ4 kK=+lL[mM]nN{oO}pP\qQ/rR,sS.tT?uUvV>xX~yY | zZ`wW$;
$code='';
$alplhaLenght=strlen($alphabet)-1;

对于($i=1;$i unique=实际上没有相同的值。每个令牌都与一个唯一的电子邮件地址相关联。也许我们可以
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;
}
$alphabet = "aA1!bB2@cC3#dD5%eE6^fF7&gG8*hH9(iI0)jJ4-kK=+lL[mM]nN{oO}pP\qQ/rR,sS.tT?uUvV>xX~yY|zZ`wW$";
$code = '';
$alplhaLenght = strlen($alphabet )-1;
for ($i = 1; $i <= 10; $i++) {
    $n = rand(1, $alplhaLenght );
    $code .= $alphabet [$n];
}