gpt4 book ai didi

PHP 种子、确定性、加密安全 PRNG(伪随机数生成器)。可能吗?

转载 作者:可可西里 更新时间:2023-11-01 12:52:10 26 4
gpt4 key购买 nike

我需要在 PHP 中创建一个可证明公平(确定性和种子)加密安全 (CS) 随机数生成器。我们正在运行 PHP 5,而 PHP 7 现在并不是一个真正的选择。但是,我找到了 PHP 7 的新 CS 函数的 polyfill,所以我已经实现了该解决方案 (https://github.com/paragonie/random_compat)。

我认为 srand() 可用于为 random_int() 设置种子,但现在我不确定是否是这样。 CSPRNG 甚至可以播种吗?如果可以播种,输出是否是确定性的(相同的随机结果,给定相同的种子)?

这是我的代码:

require_once($_SERVER['DOCUMENT_ROOT']."/lib/assets/random_compat/lib/random.php");

$seed_a = 8138707157292429635;
$seed_b = 'JuxJ1XLnBKk7gPASR80hJfq5Ey8QWEIc8Bt';

class CSPRNG{
private static $RNGseed = 0;

public function generate_seed_a(){
return random_int(0, PHP_INT_MAX);
}

public function generate_seed_b($length = 35){
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randomString = '';
for($i = 0; $i < $length; $i++){
$randomString .= $characters[random_int(0, strlen($characters) - 1)];
}
return $randomString;
}

public function seed($s = 0) {
if($s == 0){
$this->RNGseed = $this->generate_seed_a();
}else{
$this->RNGseed = $s;
}
srand($this->RNGseed);
}

public function generate_random_integer($min=0, $max=PHP_INT_MAX, $pad_zeros = true){
if($this->RNGseed == 0){
$this->seed();
}
$rnd_num = random_int($min, $max);
if($pad_zeros == true){
$num_digits = strlen((string)$max);
$format_str = "%0".$num_digits."d";
return sprintf($format_str, $rnd_num);
}else{
return $rnd_num;
}
}

public function drawing_numbers($seed_a, $num_of_balls = 6){
$this->seed($seed_a);
$draw_numbers = array();
for($i = 0; $i < $num_of_balls; $i++) {
$number = ($this->generate_random_integer(1, 49));
if(in_array($number, $draw_numbers)){
$i = $i-1;
}else{
array_push($draw_numbers, $number);
}
}
sort($draw_numbers);
return $draw_numbers;
}
}

$CSPRNG= new CSPRNG();

echo '<p>Seed A: '.$seed_a.'</p>';
echo '<p>Seed B: '.$seed_b.'</p>';
$hash = hash('sha1', $seed_a.$seed_b);
echo '<p>Hash: '.$hash.'</p>';

$drawNumbers = $CSPRNG->drawing_numbers($seed_a);
$draw_str = implode("-", $drawNumbers);
echo "<br>Drawing: $draw_str<br>";

运行此代码时,绘图 ($draw_str) 应该在每次运行时都相同,但事实并非如此。

为了证明抽奖是公平的,在中奖号码被选中并显示之前,先选择一个种子(种子A)。还会生成另一个随机数(种子 B)。种子 B 用作盐并与种子 A 结合,结果被散列。此散列在绘图之前显示给用户。他们还将获得源代码,以便在中奖号码被选中时,两个种子都会被显示出来。他们可以验证哈希是否匹配并且一切都公平地完成。

最佳答案

Duskwuff 问:

How do you intend to prove that the seed was chosen fairly? A suspicious user can easily claim that you picked a seed that would result in a favorable outcome for specific users, or that you revealed the seed to specific users ahead of time.

在调查解决方案之前,您要解决的问题究竟是什么?您的威胁模型是什么?


听起来你想要SeedSpring (0.3.0 版本支持 PHP 5.6 )。

$prng = new \ParagonIE\SeedSpring\SeedSpring('JuxJ1XLnBKk7gPAS');
$byte = $prng->getBytes(16);
\var_dump(bin2hex($byte));

这应该总是返回:

string(32) "76482c186f7c5d1cb3f895e044e3c649"

这些数字应该是公正的,但由于它基于预先共享的种子,因此根据严格的定义,它不是加密安全的。

请记住,SeedSpring 是作为玩具实现/概念验证创建的,而不是 Paragon Initiative Enterprises 的官方开源安全解决方案,因此请随意 fork 并调整它以适合您的目的。 (我怀疑我们的分支永远不会达到“稳定的 1.0.0 版本”)。

(此外,如果您要接受/奖励这些答案中的任何一个,Aaron Toponce 的答案更正确。使用 ECB 模式加密随机数比使用 AES 加密一长串 NUL 字节的性能更高- CTR,以获得大致相同的安全优势。这是 ECB 模式可用的极少数情况之一。)

关于PHP 种子、确定性、加密安全 PRNG(伪随机数生成器)。可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35245457/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com