【问题标题】:/dev/urandom error (permission denied by webhost)/dev/urandom 错误(webhost 拒绝权限)
【发布时间】:2016-04-03 08:16:05
【问题描述】:

我正在使用函数:

private function random($len) {
        if (@is_readable('/dev/urandom')) {
            $f=fopen('/dev/urandom', 'r');
            $urandom=fread($f, $len);
            fclose($f);
        }

        $return='';
        for ($i=0;$i<$len;++$i) {
            if (!isset($urandom)) {
                if ($i%2==0) mt_srand(time()%2147 * 1000000 + (double)microtime() * 1000000);
                $rand=48+mt_rand()%64;
            } else $rand=48+ord($urandom[$i])%64;

            if ($rand>57)
                $rand+=7;
            if ($rand>90)
                $rand+=6;

            if ($rand==123) $rand=52;
            if ($rand==124) $rand=53;
            $return.=chr($rand);
        }
        return $return;
    }

我有一些表单触发了这个功能,我得到了错误:

int(2) string(200) "is_readable(): open_basedir 限制生效。 文件(/dev/urandom)不在允许的路径中:

有没有办法替换这个函数而不使用/dev/urandom? 非常感谢。

【问题讨论】:

    标签: php random code-generation


    【解决方案1】:

    来自(以前接受的)答案:

    你可以用“rand”代替urandom:

    Nooooooooo!


    处理 open_basedir 是我们在 random_compat 中优雅处理的事情之一。认真考虑导入该库,然后仅使用 random_bytes() 而不是从 /dev/urandom 读取。

    无论你做什么,DON'T USE rand()。即使您认为它有用例,the security trade-offs are a lie

    另外,如果您需要一个函数来生成随机字符串(取决于 PHP 7 或 random_compat):

    /**
     * Note: See https://paragonie.com/b/JvICXzh_jhLyt4y3 for an alternative implementation
     */
    function random_string($length = 26, $alphabet = 'abcdefghijklmnopqrstuvwxyz234567')
    {
        if ($length < 1) {
            throw new InvalidArgumentException('Length must be a positive integer');
        }
        $str = '';
        $alphamax = strlen($alphabet) - 1;
        if ($alphamax < 1) {
            throw new InvalidArgumentException('Invalid alphabet');
        }
        for ($i = 0; $i < $length; ++$i) {
            $str .= $alphabet[random_int(0, $alphamax)];
        }
        return $str;
    }
    

    演示代码:https://3v4l.org/DOjNE

    【讨论】:

    • 它返回错误:致命错误:Call to undefined function random_int() in 在行:$str .= $alphabet[random_int(0, $alphamax)];
    • 您需要 random_compat 或 PHP 7。
    • 我将 /libfolder 从 random_compat 脚本上传到我的服务器,并在代码中包含了 random.php。现在我回到错误:int(2) string(200) "is_readable(): open_basedir restriction in effect. File(/dev/urandom) is not within the allowed path(s):
    • 非常感谢。你为我解决了两件事:安全性和错误修复。
    • 我的主机有PHP 5.6.16,这触发了错误Fatal error: Call to undefined function random_int()。随机兼容脚本解决了这个问题。
    【解决方案2】:

    如果您的主机不支持 random_int(),您可以使用我为自己制作的函数。

    function generateRandomString($length, $secureRand = false, $chars="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") {
        if (!function_exists("random_int") && $secureRand) {
            function random_int($min, $max) {
                $range = $max - $min;
                if ($range <= 0) return $min;
    
                $log = ceil(log($range, 2));
                $bytes = (int)($log / 8) + 1;
                $filter = (int)(1 << ((int)($log + 1))) - 1;
                do {
                    $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes, $s)));
                    if (!$s) continue;
                    $rnd = $rnd & $filter;
                } while ($rnd > $range);
    
                return $min + $rnd;
            }
        }
    
        $charsCount = strlen($chars) - 1;
        $output = "";
        for ($i=1; $i <= $length; $i++) {
            if ($secureRand)
                $output .= $chars[random_int(0, $charsCount)];
            else
                $output .= $chars[mt_rand(0, $charsCount)];
        }
        return $output;
    }
    

    如果您需要一个安全的随机字符串(例如随机密码):

    generateRandomString(8, true);
    

    这会给你一个 8 长的字符串。

    【讨论】:

      猜你喜欢
      • 2012-05-14
      • 1970-01-01
      • 1970-01-01
      • 2011-10-15
      • 1970-01-01
      • 2018-07-19
      • 2016-09-25
      • 2015-09-16
      • 2012-02-11
      相关资源
      最近更新 更多