6

在 PHP 中,我注意到一些框架使用 microtime() 函数来生成密码重置令牌,如下所示:

  $token = md5(microtime());

这是一个安全问题吗?如果攻击者能够将时钟与服务器同步到一定程度的准确度,他们就可以暴力破解令牌。1 秒同步只需要 1,000,000 次尝试,这并不是什么疯狂的问题。

这种攻击成功的可能性有多大?是否应该使用 /dev/urandom 或 openssl_pseudo_bytes() 生成令牌?microtime() 是不好的做法吗?

4

3 回答 3

4

是的,这是一个安全问题!随着时间的推移生成令牌是一种非常糟糕的做法。 Burp Suite使攻击者可以轻松破解可预测的令牌,并且基于时间的令牌非常可预测。Burp 允许人们轻松收集令牌并对它们进行统计分析以确定熵。使用此信息,您可以轻松预测未来的令牌。

请记住,攻击者只需要正确处理一次。错误数百万次没有任何区别。

这是一篇关于令牌生成的有用(也是最近的)StackOverflow 帖子,可能对您有所帮助: REST Web Service authentication token implementation

于 2013-03-20T17:22:10.557 回答
0

令牌应始终随机创建,而不是微时间。现在提供一些额外的安全性(因为,让我们再次面对它:计算机除了计算之外什么都不能做),你会想看看 php 的例子: http: //php.net/manual/de/function.srand.php 另请参阅http://php.net/manual/de/function.chr.php以轻松创建“完全”随机字符串。这是我的做法

mt_srand((double) microtime() * 1000000);
    function random_string ($length = 16)
    {
        $string = "";
        for ($n = 0; $n < count($length); $n++) $string .= chr(rand(32, 126));
        return $string;
    }

于 2013-03-20T15:32:32.000 回答
0

是的,它是(我认为)。
黑客可能会在 1 到 2 小时内猜出密码。(如果服务器使用限制可以进行多少重置,黑客可以通过使用僵尸网络或通过大量时间和大量试验来避免它。

如果我是你,我会添加静态盐。盐应该从配置(或其他安全的地方)加载。盐不应由服务器自己或任何人设置。它应该由真正的随机 API 生成(谷歌应该可以帮助你,但我猜 random.org 提供了一个)。
如果您无法使用该 API,那么伪盐应该会有所帮助,只要该死的人不知道服务器何时设置(或者服务器管理员有时可能会删除它,但不是自动的!)

例子:

$salt = null;
include('protectedDir/salt.php'); // Here should stand "$salt = ''"
if ($salt == null){
// Using real random api
file_put_contents('protectedDir/salt.php', '<?php \$salt = \'$salt\'; ?>)";
}

$resetKey = sha1(microtime() . $salt);

// 可能包含错误。未经测试。这只是一个示例,不应通过复制和粘贴来实现。

如果黑客可以访问 php 文件('protectedDir/salt.php')“源代码”,他也应该能够看到数据库配置。这将是一个更大的问题。

于 2013-03-20T15:50:41.253 回答