folm / random_compat
PHP 5.x 版本的 random_bytes() 和 random_int() 多版本兼容库,由 PHP 7 提供
Requires
- php: >=5.2.0
Requires (Dev)
- phpunit/phpunit: 4.*|5.*
Suggests
- ext-libsodium: Provides a modern crypto API that can be used to generate random bytes.
- dev-master
- v9.99.99.x-dev
- v2.0.18
- v2.0.17
- v2.0.16
- v2.0.15
- v2.0.14
- v2.0.13
- v2.0.12
- v2.0.11
- v2.0.10
- v2.0.9
- v2.0.8
- v2.0.7
- v2.0.6
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v1.x-dev
- v1.4.3
- v1.4.2
- v1.4.1
- v1.4.0
- v1.3.1
- v1.3.0
- v1.2.3
- v1.2.2
- v1.2.1
- v1.2.0
- 1.1.6
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.10
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- v1.0.1
- v1.0.0
- v0.9.7
- 0.9.5
- 0.9.4
- 0.9.3
- 0.9.2
- 0.9.1
- 0.9.0
This package is auto-updated.
Last update: 2024-09-28 05:02:17 UTC
README
PHP 5.x 版本的 random_bytes()
和 random_int()
多版本兼容库由 Paragon Initiative Enterprises 创建和维护。
虽然这个库应该在更早版本的 PHP 中也能工作,但我们只考虑与支持的 PHP 版本相关的 issue。如果正在使用不受支持的 PHP 版本,请尽快升级。
重要
尽管这个库已经由 PHP 社区的一些安全专家检查过,但仍然有可能忽略某些内容。在考虑在生产环境中部署它之前,请让您的信任黑客检查其实施错误和漏洞。
不要使用 master 分支,请使用稳定版本。
关于这个库的背景,请参考我们关于在 PHP 中安全生成随机整数和字符串的博客文章。
可用性说明
如果 PHP 无法安全地生成随机数据,则此库将抛出 Exception
。它永远不会回退到不安全的随机数据。如果这种情况持续发生,请立即升级到较新的 PHP 版本。
安装
使用Composer
# For libraries and frameworks that support PHP 5 but may be used by
# other software that only supports PHP 7:
composer require paragonie/random_compat:\>=2
# For software that explicitly needs PHP 5 support:
composer require paragonie/random_compat:\<9.99
签名 PHP 存档
从版本 1.2.0 开始,我们还在 Github 上的每个稳定版本中提供 ECDSA 签名的 PHP Archive。
- 下载
.phar
,.phar.pubkey
和.phar.pubkey.asc
文件。 - (推荐但不强制) 使用Paragon Initiative Enterprises 的 PGP 公钥验证
.phar.pubkey
的 PGP 签名(包含在.asc
文件中)。 - 将
.phar
和.phar.pubkey
文件提取到同一目录。 require_once "/path/to/random_compat.phar";
- 当发布新版本时,您只需替换
.phar
文件;.pubkey
不会更改(除非我们的签名密钥受到损害)。
手动安装
- 下载稳定版本。
- 将文件提取到您的项目中。
require_once "/path/to/random_compat/lib/random.php";
入口应该是 lib/random.php
,而不是/lib
中的其他任何文件。
使用方法
此库公开了 PHP 7 中添加的 CSPRNG 函数,以便在 PHP 5 项目中使用。它们的行为应该是一致的。
生成一个随机字节字符串
try { $string = random_bytes(32); } catch (TypeError $e) { // Well, it's an integer, so this IS unexpected. die("An unexpected error has occurred"); } catch (Error $e) { // This is also unexpected because 32 is a reasonable integer. die("An unexpected error has occurred"); } catch (Exception $e) { // If you get this message, the CSPRNG failed hard. die("Could not generate a random string. Is our OS secure?"); } var_dump(bin2hex($string)); // string(64) "5787c41ae124b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2eeac6f"
生成两个给定整数之间的随机整数(包括两个整数)
try { $int = random_int(0, 255); } catch (TypeError $e) { // Well, it's an integer, so this IS unexpected. die("An unexpected error has occurred"); } catch (Error $e) { // This is also unexpected because 0 and 255 are both reasonable integers. die("An unexpected error has occurred"); } catch (Exception $e) { // If you get this message, the CSPRNG failed hard. die("Could not generate a random int. Is our OS secure?"); } var_dump($int); // int(47)
异常处理
在处理异常和错误时,必须考虑到 PHP 5 和 PHP7 之间的差异。
差异
- 在捕获
Error
时,只要在捕获Exception
之前,就可以正常工作。 - 在没有之前捕获
Error
的情况下,捕获Exception
具有不同的行为。 - 没有通用的方法来捕获所有错误/异常。
我们的建议
始终在捕获 Exception
之前捕获 Error
。
示例
try { return random_int(1, $userInput); } catch (TypeError $e) { // This is okay, so long as `Error` is caught before `Exception`. throw new Exception('Please enter a number!'); } catch (Error $e) { // This is required, if you do not need to do anything just rethrow. throw $e; } catch (Exception $e) { // This is optional and maybe omitted if you do not want to handle errors // during generation. throw new InternalServerErrorException( 'Oops, our server is bust and cannot generate any random data.', 500, $e ); }
故障排除
异常:"无法收集足够的随机数据"
如果抛出异常,则表示您的操作系统不安全。
- 如果您使用的是Windows,请确保已启用mcrypt。
- 如果您使用的是其他操作系统,请确保
/dev/urandom
可读。- FreeBSD监狱需要从主机操作系统公开
/dev/urandom
- 如果您使用
open_basedir
,请确保/dev/urandom
被允许
- FreeBSD监狱需要从主机操作系统公开
此库不(也不会接受任何回退到不安全随机数生成器的补丁)。
与[其他PHP项目]版本冲突
如果您正在使用在其composer.json中包含如下行的一个项目
"require" {
...
"paragonie/random_compat": "~1.1",
...
}
...然后您尝试添加random_compat 2(或另一个显式要求random_compat 2的库,例如这个安全的PHP加密库),您将遇到版本冲突。
解决方案是让项目更新其需求字符串,以允许使用2及以上版本,而不是将用户硬锁定在版本1。
"require" { ... - "paragonie/random_compat": "~1.1", + "paragonie/random_compat": ">=1", ... }
版本9.99.99
注意:有一个特殊版本称为9.99.99
,它使此库不执行任何操作,但只能在PHP 7上安装。
如果您正在编写支持PHP 5的软件(例如库),但可能被不支持PHP 5的软件使用,您希望允许安装9.99.99
。上面的diff就是您想要的。
相反,如果您正在编写的软件(本身)支持PHP 5,您不希望安装9.99.99,因此您希望进行以下更改
"require" { ... - "paragonie/random_compat": "~1.1", + "paragonie/random_compat": ">=1 <9.99", ... }
为了避免安装“空”版本9.99.99
,您可以在根composer.json
中添加replace
部分
"replace": {
"paragonie/random_compat": "9.99.99"
},
清单读取长度错误
如果您使用的是PHP Archive(Phar)方法而不是Composer,并且您收到类似“清单读取长度为{int1}
应该是{int2}
”的错误消息,则Phar扩展可能未启用。
请参阅此评论以获取有关如何解决此问题的具体指导。
贡献者
如果没有以下个人的贡献,该项目将远远达不到今天的水平
- @AndrewCarterUK (Andrew Carter)
- @asgrim (James Titcumb)
- @bcremer (Benjamin Cremer)
- @chriscct7 (Chris Christoff)
- @CodesInChaos (Christian Winnerlein)
- @ConnorVG (Connor S. Parks)
- @cs278 (Chris Smith)
- @cweagans (Cameron Eagans)
- @dd32 (Dion Hulse)
- @geggleto (Glenn Eggleton)
- @glensc (Elan Ruusamäe)
- @GrahamCampbell (Graham Campbell)
- @ircmaxell (Anthony Ferrara)
- @jdevalk (Joost de Valk)
- @jedisct1 (Frank Denis)
- @juliangut (Julián Gutiérrez)
- @kelunik (Niklas Keller)
- @lt (Leigh)
- @MasonM (Mason Malone)
- @menkaff (Mehran NikNafs)
- @mmeyer2k (Michael M)
- @narfbg (Andrey Andreev)
- @nicolas-grekas (Nicolas Grekas)
- @ocean90 (Dominik Schilling)
- @oitta
- @oucil (Kevin Farley)
- @philios33 (Phil Nicholls)
- @redragonx (Stephen Chavez)
- @relaxnow (Boy Baukema)
- @rchouinard (Ryan Chouinard)
- @rugk
- @SammyK (Sammy Kaye Powers)
- @scottchiefbaker (Scott Baker)
- @skyosev (Stoyan Kyosev)
- @sthen (Stuart Henderseon)
- @stof (Christophe Coevoet)
- @teohhanhui (Teoh Han Hui)
- @tom-- (Tom Worster)
- @tsyr2ko
- @trowski (Aaron Piotrowski)
- @twistor (Chris Lepannen)
- @vinkla (Vincent Klaiber)
- @voku (Lars Moelleken)
- @xabbuh (Christian Flothmann)