2015-04-07 260 views
5

我一直在试图找到有关password_verify()是否使用长度恒定时间比较以避免计时攻击的信息。PHP password_verify()和慢等于比较

现在,简单的例子:

$hash = '$2y$10$HH3906lfby7HOy1N3duQh.Kju.84ct6AcMZm2p/SYZsZSXuYWvvT.'; 

$startTime = microtime(TRUE); 
password_verify('rasmuslerdorf', $hash); 
$endTime = microtime(TRUE); 

$time = $endTime - $startTime; 

这总是产生输出略有不同,其中,根据this article“为什么这个页面上的散列码比较哈希‘长度不变’的时间? “段落),可以用于定时攻击来拾取散列。我认为这些结果看起来相当随意,但它们肯定不是恒定的。

问题是password_verify()是否使用长度恒定的时间比较来避免定时攻击?文档中没有关于它的信息,并且由于我的浅层经验,我无法很好地解释函数处理时间结果。

回答

8

答案是肯定的,它使用长度恒定的时间比较。

这是PHP的password_verify功能的摘录

/* We're using this method instead of == in order to provide 
* resistance towards timing attacks. This is a constant time 
* equality check that will always check every byte of both 
* values. */ 
for (i = 0; i < hash_len; i++) { 
    status |= (ret->val[i]^hash[i]); 
} 

你可以看看完整的源代码在https://github.com/php/php-src/blob/master/ext/standard/password.c

+0

谢谢!以前从未见过这个回购。 – Nevertheless

4

简短的回答:是的,它的作用。

长答案:没有必要。

要理解为什么它是没有必要的,我们需要看看字符串进行比较:

$2y$10$9JxHB8U1QKsLS/ynplKzm.iIO7f6gtTKYA61ppVuANYxWNCA5DW1S 
$2y$10$ILlWQrYyDJvHHkxcCgjm7OThLRAmMcTzsJOZOwjaSYiRUHq8LVYde 
$2y$10$8JfydDKUNbOeiybwZ9m.j.5TC8CBqkc3RZu2DX42A4dFNpNYPWfzm 
$2y$10$qeG.53lr9PVVGN4Yk.kSZuOMpfone5kINyWVpAf2gUXPseU2WdSzK 
$2y$10$nZUgPUwiXIvCJ9BY1wbtbuV5vH6yff9CNyumFsI/NN2eJmf20iec. 

这是相同的密码的5个不同的哈希值。格式为:

$2y$10$saltsaltsaltsaltsaltsahashhashhashhashhashhashhashhas 

现在,远程攻击者(一个会是谁跑计时攻击),盐是一个秘密。当我们重新尝试尝试时,盐是一样的。例如:

stored password "test": 
hash = $2y$10$9JxHB8U1QKsLS/ynplKzm.iIO7f6gtTKYA61ppVuANYxWNCA5DW1S 

如果攻击者尝试密码 “ABC”,内部password_verify()将调用crypt("abc", hash)。这将导致:

$2y$10$9JxHB8U1QKsLS/ynplKzm.FTYpGS/gNDw4SB6YD0wEtCSPgGvtPim 

现在,让我们来看看这两个哈希值,并排:

$2y$10$9JxHB8U1QKsLS/ynplKzm.iIO7f6gtTKYA61ppVuANYxWNCA5DW1S 
$2y$10$9JxHB8U1QKsLS/ynplKzm.FTYpGS/gNDw4SB6YD0wEtCSPgGvtPim 

通知盐是一样的吗?请注意,一直到第一个.是一样的。还要注意攻击者不知道盐是什么。

如果攻击者能够计时攻击比较,那就没有用。因为他们不知道盐(因此推导出散列只是浪费时间,因为没有盐,他们无法确定密码)。

因此时间安全并不是绝对必要的。

为什么包括在内呢?因为每个人都犯错误。因为纵深防御是一个好主意。因为这个分析假设没有盐是没有用的(例如:如果一个缺陷在密码中偏向基于密码的哈希,那么在不知道盐的情况下密钥空间从72^255减少)。

总之,这是一件好事,但它并不是必须的.​​..