脱库门着实让2011年的年末过得好不热闹,以至于很少有人把剩余的目光和精力投向除密码外的安全方面,就如28号国外爆出的多语言的哈希表碰撞攻击漏洞。
关于该漏洞,网上那段PHP的测试代码已经轻松证明了它的存在,惠新宸的博客里也简单说明了它的原理以及相关补丁。
通过自己对测试代码进行了一些修改和运行后,可能由于对原理还不是十分了解,对于测试结果有点疑问还没有弄明白。。。
我的代码如下:
/** 可配置参数 */
define('TOTAL', 20 * 1000); //int,元素个数
define('BUCKET', 0); //int,只决定hash后的具体bucket位置,不影响测试结果
$n = empty($argv[1]) ? 15 : $argv[1]; //从命令行接收n值
$size = pow(2, $n); //2的n次方
$startTime = microtime(true);
$array = array();
for ($i = 0; $i <= TOTAL; ++$i) //循环条件完全相同
{
$key = $size * $i + BUCKET;
$array[$key] = 0;
}
$endTime = microtime(true);
echo '插入 ', TOTAL, ' 个恶意元素需要 ', $endTime - $startTime, ' 秒', "\n";
$startTime = microtime(true);
$array = array();
for ($i = 0; $i <= TOTAL; ++$i) //循环条件完全相同
{
$key = $i;
$array[$key] = 0;
}
$endTime = microtime(true);
echo '插入 ', TOTAL, ' 个普通元素需要 ', $endTime - $startTime, ' 秒', "\n";
通过了解原理可以知道,虽然碰撞漏洞和元素的插入数量有关(当然需要一定量的元素),但更关键的在于这些元素的特殊键值的选取。
在固定插入元素数量的情况下,pow(2, n)中n的值会对测试结果有很大影响:
n值在15左右的情况下,碰撞漏洞效果最为明显,设置过小或过大则均会逐渐趋于正常。最终结果类似正态分布(如下图)。
说明:该图为两万个元素的情况下。根据元素个数不同,曲线具体坡度也会有变化,但仍属于正态分布。
Why?