duzun / p2peg
对等熵生成器(或带有p2p播种的随机数生成器)
Requires
- php: >=5.0.0
Requires (Dev)
- apigen/apigen: ~4.1@RC
- phpunit/phpunit: ^6.1
README
或带有p2p播种的随机数生成器
关于
Node: 该库的JavaScript版本正在开发中 p2peg.js.
此类通过结合熵源来生成尽可能不可预测的随机数据。关键概念是 peers 之间共享随机数据,其中双方都从请求中受益。
内部,每个 peer 使用一些系统数据、服务器性能/负载、一些 PRNGs(伪随机数生成器)、时间和客户端提供的数据来生成随机数据。收集到的数据总是与内部状态数据结合,该数据在每个请求时都会改变,并使用 peer 的密钥通过 HMAC 进行摘要。
每个客户端-peer 通过在请求中提供变量数据(有意的或无意的)以及连接到服务器的事实(精确请求时间也计入)来增加服务器-peer 的熵,从而改变 P2PEG
的内部状态。内部状态是来自系统和所有曾经请求当前 peer 的客户端-peers 收集到的所有熵位的总和。
对于客户端-peer 来说,没有知道 P2PEG
的内部状态或关于其他客户端-peer 的方法,因此生成的数据是真正随机且不可预测的。
如果一个 peer 不信任另一个 peer 是“诚实的”,它可以联系多个 peers 来收集随机位,并将结果与自己的 PRN 和内部状态结合。
在 Web 服务器上,还可以从常见的网站客户端收集熵。
基本用法
包含类
require_once "/path/to/lib/P2PEG.php";
获取单例实例或创建一个新的 P2PEG 实例
$P2PEG = P2PEG::instance();
获取一些随机二进制字符串
$str = $P2PEG->str($length);
现在您可以使用 $str
作为密码学盐、PRNG 的种子、密码生成器或任何需要不可预测高熵数据的其他东西。
获取一些随机整数
$int1 = $P2PEG->int(); $int2 = $P2PEG->int16(); $int3 = $P2PEG->int32(); $int4 = $P2PEG->rand($min, $max, $algo="int"); // see PHP's rand() in docs
获取一些随机文本(base64 编码)
$text = $P2PEG->text($length);
获取一些随机文本(通过给定的字母表)
$text = $P2PEG->alpha('a-z0-9AUOIE!', $length); // or $text = $P2PEG->text($length, 'a-z0-9AUOIE!');
获取一些随机字符串,以十六进制编码
$hex = $P2PEG->hex($length);
获取伪随机 32 位整数 - 此方法比 int32() 生成大量数字更快,但转而使用更少的熵(参见 RNG)。
$rand_int = $P2PEG->rand32($strict=true);
获取伪随机 64 位整数 - 此方法比 int() 生成大量数字更快,但转而使用更少的熵(参见 xorshiftplus 算法)。
$rand_long = $P2PEG->rand64();
还有一些其他由 P2PEG 随机播种的 PRNGs。
// x32 $P2PEG->xorShift32($strict=true); $P2PEG->xorShift128($strict=true); $P2PEG->xorwow($strict=true); // default in Nvidia's CUDA toolkit // x64 $P2PEG->xorShift1024Star(); $P2PEG->xorShift128Plus(); $P2PEG->splitMix64();
高级用法
在使用 P2PEG
类的实例之前,设置一些属性是一个好主意
内部状态文件 - 可选。提示:通过 chmod 0600 p2peg.dat
将其设置为系统上的其他用户不可访问
$P2PEG->state_file = "/path/to/data/p2peg.dat";
在设置时选择的密钥
$P2PEG->setSecret("some uniq secret that no one knows");
用一些数据或您选择的数据对 P2PEG 进行播种
$P2PEG->seed("some (random) string");
对 PHP 的 RNG 进行播种
mt_srand(crc32($P2PEG->seed())); // or mt_srand($P2PEG->int32());
写入 /dev/random
$P2PEG->seedRandomDev("some (optional) entropy");
如果系统是 x64,则获取 56 位整数
$int64 = $P2PEG->int(7);
显示一个随机位图图像
$P2PEG->servImg($width,$height,$method='rand32',$itemSize=0);
请小心选择允许servImg()
使用的$method
,因为它可能会向客户端显示一些私有数据。以下方法可以安全地显示给客户端
$allowMethods = array( // P2PEG entropy 'int', 'int32', 'int16', 'str', 'seed', 'text', 'hex', // PRNGs seeded by P2PEG 'rand32', 'xorShift32', 'xorShift128', 'xorwow', 'rand64', 'xorShift128Plus', 'xorShift1024Star', 'splitMix64', // raw data 'dynEntropy','clientEntropy','networkEntropy', );
此方法有助于直观检查随机数生成器(RNG)。了解RNG有多好是不够的,但它可以判断RNG是否不良或存在错误。
示例
- https://duzun.me/entropy/img/rand32
- https://duzun.me/entropy/img/rand64/64
- https://duzun.me/entropy/img/str
从外部获取一些熵
$P2PEG->networkEntropy($autoseed=true);
在cron中可以调用
$P2PEG->expensiveEntropy($autoseed=true);
此方法收集一些网络熵和服务器熵,可能会非常慢。这就是为什么将其在后台调用的同时,定期调用它是一个好主意。但与此同时,定期调用它以获取更多不可预测、加密安全的熵也是一个好主意。
... 更多即将推出
示例输出
使用示例
我使用P2PEG在客户端和服务器创建了一个简单的密码生成器。每个客户端由服务器初始化,服务器也由每个客户端初始化,从而实现了P2PEG概念。