Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/254.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-rand()预测随机数的可能性_Php_Random_Security_Password Protection - Fatal编程技术网

用PHP-rand()预测随机数的可能性

用PHP-rand()预测随机数的可能性,php,random,security,password-protection,Php,Random,Security,Password Protection,这是一个很长的问题,所以简而言之,问题是,依靠PHP的rand函数生成第一次密码安全吗 在我的空闲时间,我只是在想一个逻辑,使非常困难的自定义密码生成器(只有数字),一个功能,我可能需要在我的下一个项目 首先想到的是PHP的rand()方法。我尝试了一些测试rand方法来测试它的随机行为。一般来说,首先想到的是,生成多个随机数并对其执行一些操作将使随机数更难猜测。使用以下程序,我惊讶地发现随机数的平均值非常接近其一半: $minAvg=$maxAvg=50; for($i=1;$i<=10

这是一个很长的问题,所以简而言之,问题是,依靠PHP的
rand
函数生成第一次密码安全吗

在我的空闲时间,我只是在想一个逻辑,使非常困难的自定义密码生成器(只有数字),一个功能,我可能需要在我的下一个项目

首先想到的是PHP的
rand()
方法。我尝试了一些测试
rand
方法来测试它的随机行为。一般来说,首先想到的是,生成多个随机数并对其执行一些操作将使随机数更难猜测。使用以下程序,我惊讶地发现随机数的平均值非常接近其一半:

$minAvg=$maxAvg=50;
for($i=1;$i<=1000;$i++){
    //Random average
    $sum=0;
    for($j=0;$j<1000;$j++){
        $sum=$sum+rand(1,100);
    }
    $avg=$sum/1000;
    ///

    if($avg<$minAvg){
        $minAvg=$avg;
    }
    if($avg>$maxAvg){
        $maxAvg=$avg;
    }
    if($i%100==0)
    {
        echo "at i=$i, Min Avg = $minAvg and Max Avg = $maxAvg <br/>";
    }
}
我至少运行上述代码50次,但即使在1000次迭代之后,平均值始终保持在47.xx到53.xx之间(对于1到100之间的随机数)

虽然这个结果并没有告诉我们很多,因为一般来说,少数数字的平均值必须接近中间值,但我并没有料到随机数会有同样的行为我觉得它显示了PHP的rand()使用了一些固定的算法,以给定的模式生成数字。据我所知,这是平均水平保持接近中间水平的唯一正当理由。

到目前为止,我经常使用随机数来生成第一次密码(在第一次登录时强制更改)。然而,现在我并不担心使用随机数来生成涉及金融交易和敏感信息(如信用卡号,尽管已加密)的网站的首次密码是否安全。黑客(不是业余的,而是专业的黑客)有没有可能用easy破解这些密码?最重要的是,是否有任何算法来检测(或至少估计)下一个随机数

编辑 为了更合理,用户将进行离线注册,例如开立银行账户,并且第一次打印的密码将通过邮寄而不是电子邮件发送。所以密码必须保持在10个字符以下,这就排除了任何加密。

PHP就是您要找的。用法示例:

$code = uniqid(rand(), true);

请注意,有一个更安全的函数,但它仅在PHP>5.3上可用。请先阅读问题,然后阅读以下内容作为问题的解决方案,谢谢。

你正在做一些比密码可预测性更不安全的事情,比如用电子邮件发送“第一次”密码

无论您是坚持生成密码,还是使用发送第一次自动登录URL的替代方法(我会推荐),您仍然需要防止URL的密码或密钥的可预测性

你需要像这样有很长的秘密盐(键盘随机可以):
$salt=“aslkfhaqoiey19836y9qashdhkasjdhbknmxcbnzmbakua089610”

然后使用rand()为您的URL创建第一次密码或密钥,但要结合md5和很长的salt。由于盐是秘密,没有人能预测md5会产生什么结果

$randomPassword=base64_编码(md5(rand().rand().salt,true))

rand()
不是一个加密强度RNG,但在这里它并不重要

你所需要的只是随机密码的不可预测性,以至于随机猜测是不可行的。此属性与密码的长度和允许的字符池的关系比与
rand()
的关系要大得多

此外,防止暴力强迫的最佳防线是在登录尝试之间引入故意延迟。如果你这样做,并且拥有“合理随机”的密码,你绝对不会被强制使用


最后,在引擎盖下,
rand()。除非服务器将花费大部分时间生成密码(高度可疑),否则您可以通过切换到
mt_rand()
,获得“更好的”随机性,这是的一种实现(仍然不是加密强度).php中生成安全随机数的一种相对简单的方法是使用
mcrypt\u-create\u-iv
mcrypt\u-DEV\u-uradom
作为
$source
。i、 e.
mcrypt\u create\u iv(大小,mcrypt\u DEV\u uradom)
。然后将生成的随机字节转换为您需要的任何形式。

也许您想查看一下
rand()
函数的名称。这对于密码来说会不会有点太长?你知道,很多人都是自己打单词的。不,MD5是固定长度的,32个十六进制字符(base16表示法)或更少的base64。当然,您可以始终对其进行子串,并且只发送6个字符。现在,请告诉我,我需要重写16个字符长的base64编码密码多少次才能正确执行?这个答案解决了密码的可预测性问题。为什么要投否决票?现在在第一时间就写好这个密码:
Jrh6TtWkzDa+/Y0pVmxNNA==
这就是你的脚本生成的。在这种情况下,
mt_rand
的优势可以忽略不计,因为无论哪种方式,种子都非常糟糕。@CodesInChaos:尽管我同意,只要RNG没有完全损坏,它的用途就不重要,但我不明白你怎么能如此随意地量化优势(假设存在优势)或答案的哪一部分值得否决票。你能提供一些具体的反馈吗?它包含时间和进程id。这最多是一个32位的值。但由于两者都是可预测的,我把实际熵放在这个值的一半以下。在这种情况下,PRNG的质量远不如种子的质量重要。
rand
mt_rand
的播种方式基本相同,因此
mt_rand
的优势可以忽略不计。如果人们能体面地播种他们的非加密PRNG,我会少抱怨很多,但他们不会
$code = uniqid(rand(), true);