【问题标题】:Is this approach to generating a "random" number from a sha512 hash effective? [closed]这种从 sha512 哈希生成“随机”数字的方法是否有效? [关闭]
【发布时间】:2014-03-08 20:23:33
【问题描述】:

我希望举办一次小型抽奖活动,但我希望人们能够验证所选择的号码是否公平。我知道一些网站使用“可证明公平”系统来实现这一点,其中用户输入与一个秘密字符串相结合,然后对其进行散列以确定中奖号码。一旦秘密字符串被释放,参与者可以使用哈希来验证选择了正确的获胜者。

应该从 sha512 哈希中生成一个从 0 到 n 的“随机”数字(n 的长度不同,但最多为 255)以确定获胜者。这是我想到的:

创建一个长度为 n 的数组并插入可以出现在 sha 哈希中的字符对。例如,如果 n 为 255,则数组将具有:array('aa','ab','ac'...'fd','fe','ff'...'97','98','99')。基本上,它会使用 a-f 和 0-9 来组合两个字符。

然后它会查看哈希的前两个字符并使用 array_search 来查看该对是否存在于数组中。如果是,它的索引是选择的数字,否则它会移动到下一对字符并搜索那些。在极少数情况下,它找不到匹配项,它会不断对自身进行哈希处理,并使用返回的新哈希值继续搜索。

$values = array('a','b','c','d','e','f','0','1','2','3','4','5','6','7','8','9');
$numbers = array();
$ENTRANTS = 50;
$rand =  md5(uniqid(rand(), true)); //This would instead be $secret . $user_input
$hash = hash('sha512',$rand); 

$values_index = 0;
$current = $values[$values_index];
$options = 0;
while ($options < $ENTRANTS){
    $remaining = ($ENTRANTS - $options > 15)? 16: $ENTRANTS-$options;
    for ($n=0; $n < $remaining ;$n++){
        array_push($numbers, $current . $values[$n]);
        $options++;
    }

    $values_index++;
    $current = $values[$values_index];
}

$outcomes = array();
$winning = null;
$i = 0;

while (empty($winning)){

    while ($i+1 < 64 && empty($winning)){
        $combo = $hash[$i] . $hash[$i+1];
        $number = array_search($combo,$numbers);
        if ($number !== false){
            $winning = $number;
        }

        $i++;
    }

    if (!empty($winning)){
        echo "<pre>" . print_r($numbers,true) . "</pre>";
        echo $hash . "<br>" . $winning;
    }
    else {
        echo "re-hashing" . "<br>";
        $hash = hash("sha512",$hash);
        $i = 0;
    }
}

这在测试时有效,但我不确定它是否有效地生成了一个随机数。 sha512 散列中的字符大部分是否均匀且不可预测地分布?如果您对此有任何问题或对如何改进有任何建议,请告诉我!

【问题讨论】:

标签: php hash cryptography sha


【解决方案1】:

最好的方法 - 与加密货币一样 - 如果可以避免的话,不要推出自己的安全性。作为您的随机数生成器rand() is not cryptographically secure(请参阅注释部分)。对其应用哈希不会使这个随机数生成器安全。实际上,用(一组)坏的 RNG 做出好的 RNG 是不可能的。

相反,使用openssl_random_pseudo_bytes 会更好。有no need to perform any post processing on the bytes you get from that random number generator - 至少不增加加密强度。

【讨论】:

    猜你喜欢
    • 2010-11-01
    • 2013-05-13
    • 1970-01-01
    • 2014-04-06
    • 2012-01-28
    • 2021-11-05
    • 2014-11-29
    • 2011-10-01
    • 2011-08-17
    相关资源
    最近更新 更多