从PHP访问CryptGenRandom

时间:2011-12-18 18:05:15

标签: php windows security random

我很难找到一种方法从PHP访问Windows上的安全随机数,这种方式很有可能在任何给定的安装上工作。

  • 许多Windows安装没有openssl或禁用,所以openssl_random_pseudo_bytes()通常不起作用。

  • 当mycrypt扩展程序不可用时mcrypt_create_iv()出现同样的问题。

  • session_id()(将session.entropy_length设置为合理的数字)是另一种路由,但安全模式有时会禁用重新生成和获取会话ID所需的功能。

  • new COM('CAPICOM.Utilities.1')->GetRandom()有点过时(仅限Win32),并且dll不可靠。

  • 带有new DOTNET('mscorlib', 'System.Security.Cryptography.RNGCryptoServiceProvider')
  • GetBytes()仅在安装了.NET且与PHP兼容的情况下才有效。

什么是更好的解决方案?

1 个答案:

答案 0 :(得分:4)

我实际上在PHP中实现了一个RFC4086兼容的随机数生成器。您可以在the GitHub Project for PHP-CryptLib找到工作。

基本上,您指定所需的随机数/字符串的“强度”。如果您需要加密安全数字,请选择高(但请注意,这可能是一个阻止操作。如果您只需要良好的强度数字/字符串,我建议使用中等设置。如果您只是实施一个没有安全隐患的游戏,选择低。

所以这是如何使用它:

require_once dirname(dirname(__DIR__)) . '/lib/CryptLib/bootstrap.php';
$factory = new \CryptLib\Random\Factory;
$generator = $factory->getLowStrengthGenerator();
$number = $generator->generate(8);

这将产生低强度的8字节字符串(chr 0-255)(你可以做 - > getHighStrengthGenerator用于高强度)。不同之处在于它如何设置生成器(它使用哪个混合器,以及它使用的源)。

生成1到10(含)之间的整数:

$int = $generator->generateInt(1, 10);

请注意,RFC4086指定了一种从多个源生成随机性的方法(这样,如果任何一个源被泄露,最终结果将不会显着减弱)。因此,当您选择高强度源时,它使用与中等源相同的源,但从高强度类别添加一个或多个。

请注意,根据RFC,输出的强度至少与使用的最强的非危害源一样好。所以这对于你可以获得的应用程序(设计)来说真的是最优质的RNG ......如果你想添加硬件TRNG,你可以并且仍然使用这种机制(源是可插入的,所以它应该能够在不损害输出的情况下添加任何东西)...