2

我希望在 PHP 中生成一个 UUID(版本 4),但是我所看到的所有方法都mt_rand()希望避免使用,因为如果可以猜到生成的 UUID,它会带来安全隐患。

我想出了以下几点:

function uuid_v4()
{
    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        // 32 bits for "time_low"
        random_mcrypt(), random_mcrypt(),

        // 16 bits for "time_mid"
        random_mcrypt(),

        // 16 bits for "time_hi_and_version",
        // four most significant bits holds version number 4
        random_mcrypt(0x0fff) | 0x4000,

        // 16 bits, 8 bits for "clk_seq_hi_res",
        // 8 bits for "clk_seq_low",
        // two most significant bits holds zero and one for variant DCE1.1
        random_mcrypt(0x3fff) | 0x8000,

        // 48 bits for "node"
        random_mcrypt(), random_mcrypt(), random_mcrypt()
    );
}

function random_mcrypt($max = 0xffff)
{
    $int = current(unpack('S', mcrypt_create_iv(2, MCRYPT_DEV_URANDOM)));
    $factor = $max / 0xffff;
    return round($int * $factor);
}

这足以满足我的需求吗?有什么我应该注意的吗?

编辑:这已被标记为重复,这不是因为我的问题我说其他答案(包括他被标记为重复的答案)使用我出于安全原因不想使用的 mt_rand() 。

编辑 2:需要明确的是,这不是关于如何生成 v4 UUID 的问题,而是我的方法是否提高了使用方法实现的安全性mt_rand()以及我应该知道的任何陷阱。

4

1 回答 1

1

是否足以满足您的需求取决于您的威胁模型。你有一群孩子想惹你,担心企业间谍活动,还是整个中国政府都在试图破坏你的系统?

MCRYPT_DEV_URANDOM从 /dev/urandom 生成熵。这避免了对 /dev/random 的 DOS 攻击,您需要一堆 UUID 并耗尽系统熵,直到程序阻塞。但是,这也意味着您绝对无法保证 UUID 中实际有多少位熵 - 没有任何保证。

已经编写了威胁模型,这些模型首先假设您使用数千个请求 ping 服务器以耗尽 /dev/urandom 的熵,然后开始破解 urandom 密钥。

如果您真的关心安全性,那么有一些旨在确保安全的加密 PRNG,例如 Blum Blum Shub。

于 2013-09-14T23:59:11.120 回答