【问题标题】:using rand() for CSRF, can it be safe(r)?将 rand() 用于 CSRF,它可以安全吗(r)?
【发布时间】:2014-01-15 11:11:59
【问题描述】:

我有这个CSRF保护功能,太疯狂了。

function GenToken($ranLen) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$()';
    $randomString = '';
    for ($i = 0; $i < $ranLen; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}

它是这样调用的:

$token = GenToken(rand(32,128));

它使用 PHP 的 rand(),我知道它在创建随机数方面远非理想。

我想知道的是它有多糟糕?此功能是否适用于“良好”(被授予古怪)CSRF 保护?它肯定会生成一个字符串。

目前该功能仅用于 CSRF,但它可以用于其他短随机字符串,例如通过电子邮件发送给用户以激活其帐户等的代码。这可以接受吗?

【问题讨论】:

  • 对你的目的来说没问题,它会非常随机,无法“预测”。
  • 关于通过电子邮件激活,只要您不让心怀恶意的人尝试无数次使用不同代码的激活请求,这可能是可以的(这也意味着您的激活密码不应该太短了)。
  • 可能与您的问题有关:stackoverflow.com/a/7808258/1961059
  • 谢谢,看来把rand()简单地改成mt_rand()总比没有好。
  • @TraceRace - 使用openssl_random_pseudo_bytes,它将完美无缺。

标签: php random


【解决方案1】:

只要生成的令牌是特定于用户的和/或相对较快过期,这可能就足够了。但是,如果您要对其进行更改,则应将其更改为使用体面的 PRNG,它在大多数系统上以 /dev/random 的形式提供,并且可以通过多种方式访问​​:

mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM)
openssl_random_pseudo_bytes($raw_salt_len)
fopen('/dev/urandom', 'r')  // then fread enough bytes from it

只需bin2hexbase64_encode 以上的返回值。您的rand(或更好的mt_rand)解决方案应该只是在以上都不可用的情况下的后备方案。

【讨论】:

  • 谢谢。这种方法在速度和可扩展性方面如何?如果我在已经加载的服务器上不断生成随机数,我会遇到问题吗?
  • 一直在试验这个return substr(base64_encode(openssl_random_pseudo_bytes($len)), 0, $len);,其中$len 是令牌的字符长度(即32-128)。看起来很有希望,你能看出这样的解决方案有什么问题吗?
  • 我认为速度应该没有问题。如果您有大量的请求要服务,您可能会耗尽/dev/random 的熵池,但实际上这没问题,您仍然会得到不比@987654331 差的随机数@。如果您使用bin2hex 而不是base64_encode,则只需读取$len/2 字节即可获得所需的长度,而无需substr(编码为十六进制的字节长度只需加倍)。
【解决方案2】:

对于类似的任务,我更喜欢使用名为 uniqid http://www.php.net/manual/en/function.uniqid.php 的内置 php 函数 它应该比你的实现更快、更安全

【讨论】:

  • PHP 文档说...without being passed any additional parameters the return value is little different from microtime(). 你能解释一下这是一个更安全的实现吗?我想你使用more_entropy 标志?
  • 好吧,它可能同样安全,但无论如何更快。对于一个真正更安全的随机序列,我会使用openssl_random_pseudo_bytes,但不适用于你的情况,那是矫枉过正
猜你喜欢
  • 1970-01-01
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-08
  • 2021-06-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多