【问题标题】:How do you generate cryptographically secure random numbers with PHP? [duplicate]如何使用 PHP 生成密码安全的随机数? [复制]
【发布时间】:2009-10-11 15:23:38
【问题描述】:

可能重复:
Secure random number generation in PHP

我们需要生成一个加密随机字符串作为身份验证令牌,它将与数据库中的会话数据相关联。我们正在使用 PHP,它似乎没有内置合适的随机数生成器。我们如何使用 php 生成长度为 N 的加密安全随机字符串?

另外请注意,由于我们应用程序的性质,shell_exec 不适用。

【问题讨论】:

标签: php cryptography random


【解决方案1】:

根据您的平台,您可以使用 /dev/urandom 或 CAPICOM。 this comment from Mark Seecof 很好地总结了这一点:

“如果您需要一些伪随机位用于安全或加密目的(例如,用于块密码的随机 IV,用于密码哈希的随机盐)mt_rand() 是一个糟糕的来源。在大多数 Unix/Linux 和/或 MS-Windows 平台上您可以从操作系统或系统库中获得更高等级的伪随机位,如下所示:

<?php
// get 128 pseudorandom bits in a string of 16 bytes

$pr_bits = '';

// Unix/Linux platform?
$fp = @fopen('/dev/urandom','rb');
if ($fp !== FALSE) {
    $pr_bits .= @fread($fp,16);
    @fclose($fp);
}

// MS-Windows platform?
if (@class_exists('COM')) {
    // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
    try {
        $CAPI_Util = new COM('CAPICOM.Utilities.1');
        $pr_bits .= $CAPI_Util->GetRandom(16,0);

        // if we ask for binary data PHP munges it, so we
        // request base64 return value.  We squeeze out the
        // redundancy and useless ==CRLF by hashing...
        if ($pr_bits) { $pr_bits = md5($pr_bits,TRUE); }
    } catch (Exception $ex) {
        // echo 'Exception: ' . $ex->getMessage();
    }
}

if (strlen($pr_bits) < 16) {
    // do something to warn system owner that
    // pseudorandom generator is missing
}
?>

注意:在您的代码中尝试读取 /dev/urandom 和尝试访问 CAPICOM 通常是安全的,尽管两者都会在对方平台上静默失败。把它们都放在那里,这样你的代码就更便携了。”

【讨论】:

  • 谢谢 - 我相信这是最好的方法,因为 /dev/urandom 使用各种熵源,而不仅仅是系统时钟。然而,就我而言,我们将无法以这种方式使用 fopen,因为我们基本上是在沙盒环境中工作。
  • 更新:来自Windows Platform SDK Redistributable: CAPICOM - “CAPICOM 从适用于 Windows 7 的 Windows SDK 开始被排除在 Windows SDK 之外,尽管分发包将在 32 位版本的 Windows 7 和 Windows Server 2008 上运行R2 操作系统,不推荐使用。更多信息请参见Alternatives to Using CAPICOM"
【解决方案2】:

在我脑海中浮现:用微​​时间,将它乘以微时间 % 100 并在收到结果的 sha1 上做一些随机操作。

【讨论】:

  • 那不是很安全。除非您希望输出可预测,否则不要使用系统时钟。
  • 丹是对的。在安全性很重要的情况下,基于当前时间的种子不能提供足够的熵。
【解决方案3】:

uniqid 呢?文档有一个如何将其用于 cookie/会话的示例。

【讨论】:

  • 这似乎是最好的方法 - 当与手册中描述的 mt_rand 结合使用时。
  • uniqid 不是加密安全的,它被专门设计为永远不会返回相同的数字两次,因为它是基于系统时钟的,但是如果只有攻击者知道它的大致时间,它确实具有相当低的熵已生成。
  • @ebusiness:OP 实际上并不需要加密安全功能。 uniqid 非常适合他的情况。
  • 据我所知,我们谈论的是会话 ID,如果您能猜出某人的会话 ID,您将获得他们的特权。你如何证明不需要不可猜测的随机性?
猜你喜欢
  • 2021-06-18
  • 2017-01-15
  • 2012-07-28
  • 1970-01-01
  • 2010-12-22
  • 2016-08-15
  • 1970-01-01
  • 2014-12-27
  • 2010-11-14
相关资源
最近更新 更多