使用rand()进行CSRF,它是否安全(r)?

时间:2014-01-15 11:11:59

标签: php random

我有这个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,但它可以用于其他短随机字符串,例如通过电子邮件发送给用户以激活其帐户等的代码。这可以接受吗?

2 个答案:

答案 0 :(得分: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)解决方案应该只是一个后备,以防上述情况都不可用。

答案 1 :(得分:0)

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