PHP中与操作系统无关的随机字节序列

PHP中与操作系统无关的随机字节序列,php,security,random,Php,Security,Random,我想生成一个随机字节序列,用于安全敏感上下文。我正在寻找一种独立于操作系统的方式,因此我无法访问/dev/(u)random。此外,openssl_random_pseudo_bytes()可能不可用,所以我们也不要考虑它。我对任何情况下的性能差异也不感兴趣 查看phpass库(许多人都使用它,并且认为它足够安全)来生成随机序列,如果/dev/uradom不可用,它会返回到以下算法: // Init: $this->random_state = microtime(); if (funct

我想生成一个随机字节序列,用于安全敏感上下文。我正在寻找一种独立于操作系统的方式,因此我无法访问/dev/(u)random。此外,openssl_random_pseudo_bytes()可能不可用,所以我们也不要考虑它。我对任何情况下的性能差异也不感兴趣

查看phpass库(许多人都使用它,并且认为它足够安全)来生成随机序列,如果/dev/uradom不可用,它会返回到以下算法:

// Init:
$this->random_state = microtime();
if (function_exists('getmypid'))
    $this->random_state .= getmypid();

// Generate
$count = ...number of bytes to generate
$output = '';
for ($i = 0; $i < $count; $i += 16) {
    $this->random_state =
        md5(microtime() . $this->random_state);
    $output .=
        pack('H*', md5($this->random_state));
}
$output = substr($output, 0, $count);
// $output ready
//初始化:
$this->random_state=microtime();
如果(函数_存在('getmypid'))
$this->random_state.=getmypid();
//产生
$count=…要生成的字节数
$output='';
对于($i=0;$i<$count;$i+=16){
$this->random_state=
md5(microtime().$this->random_state);
$output=
包装('H*',md5($this->random_state));
}
$output=substr($output,0,$count);
//$output ready
上述算法基本上依赖于getmypid()、md5()和microtime()生成随机序列。许多人已经指出,时间/微时间和pid对于安全应用程序来说是一个不好的熵源,因此即使您使用md5和一些字符串操作来转换它们,输出也不会是“安全随机”的。因此我们知道,上述算法充其量只能与pid和微时间作为熵源一样好

相比之下,这里有另一个算法。鉴于rand是由PHP自动播种的,它(可能)并不比以前的算法安全性更好,因为rand/mt_rand也默认使用计算机时间和pid进行播种()。但既然它不那么复杂,它不是更好的选择吗?我还可以重新表述这个问题:鉴于上面和下面的算法都依赖于pid和计算机时间来生成随机数,那么上面的算法是否仍然优越?为什么

function RandomBytes($len)
{
    // Seed
    $seed = (double)microtime()*1000003;
    if (function_exists('getmypid'))
            $seed += getmypid();
    mt_srand($seed);

    $output = '';
    for ($i = 0; $i < $len; ++$i)
        $output .= chr(mt_rand(0, 255));

    // optionally transform using pack('H*', ...) to make output printable
    return $output;
}
函数随机字节($len)
{
//种子
$seed=(双)微时间()*1000003;
如果(函数_存在('getmypid'))
$seed+=getmypid();
穆斯兰(种子);
$output='';
对于($i=0;$i<$len;++$i)
$output.=chr(百万兰特(0255));
//可以选择使用pack('H*,…)进行转换,以使输出可打印
返回$output;
}

最后一个问题是,您知道在PHP中以独立于操作系统的方式生成随机字节的更好(=更随机)方法吗?

如果操作系统资源存在,您可以尝试使用它们,然后在这些资源不存在且您别无选择时,返回到自制的方法。请参见另一论坛上的示例


在支持.NET的Windows系统上,您可以将DOTNET php类与
System.Security.Cryptography.RNGCryptoServiceProvider
类一起使用。

如果存在操作系统资源,您可以尝试使用这些资源,但当这些资源不存在且您没有其他选择时,您可以使用自行开发的资源。请参见另一论坛上的示例


在支持.NET的Windows系统上,您可以将DOTNET php类与
System.Security.Cryptography.RNGCryptoServiceProvider
类一起使用。

如果强烈要求正确性,请小心使用操作系统实现的伪随机生成器。专门用于安全和模拟。伪随机生成器的实现并不困难,请参考一些理论和参考资料。

如果需要很强的正确性,请小心使用操作系统实现的伪随机生成器。专门用于安全和模拟。伪随机生成器不难实现,请查看一些理论和参考资料。

您可能使用的最佳随机数生成器是
/dev/random
。如果无法访问此界面,则您可以在windows系统上使用安全性较差的
system.Security.Cryptography.RNGCryptoServiceProvider
。函数
mt_rand()
的输出随机性应该排在第三位

您可能使用的最佳随机数生成器是
/dev/random
。如果无法访问此界面,则您可以在windows系统上使用安全性较差的
system.Security.Cryptography.RNGCryptoServiceProvider
。函数
mt_rand()
的输出随机性应该排在第三位

在PHP中,没有可移植且始终可用的方法来生成加密性强的随机字节序列。你需要一个特定的环境或可用的工具,而这些环境或工具是你用先决条件排除的phpass只使用rand或hash解决方案的原因是它只是将其用作密码盐,这不依赖于高熵。我确实理解,如果没有操作系统支持,我将无法生成加密安全的随机序列。但是,我展示的第二个算法与第一个算法相比如何,以及(为什么)其中一个算法比另一个更好?mt_rand和rand已经被植入种子,通过减少种子的熵,你实际上降低了这些函数的安全性。第一个算法似乎也同样植入种子。如果我删除了RandomBytes()中的种子部分,会有很大的变化吗?在PHP中,没有可移植且始终可用的方法来生成加密性强的随机字节序列。你需要一个特定的环境或可用的工具,而这些环境或工具是你用先决条件排除的phpass只使用rand或hash解决方案的原因是它只是将其用作密码盐,这不依赖于高熵。我确实理解,如果没有操作系统支持,我将无法生成加密安全的随机序列。但是,我展示的第二种算法与第一种算法相比如何,以及(为什么)其中一种算法比另一种算法更好呢?mt_rand和rand已经是种子了,你正在实际制作这些算法