我的问题与PBKDF2有关。我不知道如何用现有的散列和盐类验证用户输入的密码。
我听说过所谓的“长度常量”比较,它基本上确保每个字节都被比较,而不是简单的字符串比较。这也是我困惑的地方。当使用"Hello“作为密码和"Hello2”作为salt派生密钥时,PBKDF2的输出将始终是相同的。那么,为什么有一个慢等于(长度常数)比较法呢?
在PBKDF2中验证密码的正确方法是什么?
发布于 2014-02-23 08:09:27
如果结果散列相同,则非长度常量检查将比较结果摘要的每个字节。这将需要更多的时间来比较。
假设运行KDF需要90.00ms,完整长度比较需要0.90ms (不是实数,但对示例来说足够好)
如果密码是"hello“而不是"Hello",那么摘要很可能有一个不同的第一个或第二个字节,这意味着比较将确定它们的差异要比它们相同时快得多。而不是90.90毫秒,它可能需要90.10毫秒。
如果攻击者能够测量cpu使用情况或cpu功率图,则可以测量击键量,为攻击者提供正确密码的长度。它们还可以比较按键之间所需的时间,以更好地确定输入了什么按键组合。攻击者可能能够获得更多的信息,而这些信息可能更少,但攻击者获得的每一点信息都将帮助他们攻击KDF并恢复密码。知道一个特定的组合是正确的是大量的信息。
这就是为什么恒定时间比较如此重要的原因,因为输入伪造密码并获得比较不正确结果所需的时间是非常容易的,所以当比较正确的结果时,就会花费更长的时间,并且被任何正在测量它们的机制(软件或硬件)所检测。
发布于 2014-02-24 15:34:08
我本来会对此发表评论的,但我没有足够的口碑。
我觉得这是个好问题。我看不出时间攻击是如何以任何实际的方式进行的。我对我生成的两个256位/32字节键进行了快速测试。我在他们上面做了一个简单的"for“,比较了每个字符。这是我的测试结果。
LAST BYTE DIFFERENT:
Comparing hex representations of the keys (64 characters)
k1: 2F5F587E5057C152F8A0F7CCE30ECDC0B26D45721E6FA538AE6AD0D31D478346
k2: 2F5F587E5057C152F8A0F7CCE30ECDC0B26D45721E6FA538AE6AD0D31D478340
The same?: False
Start time: 15:18:06.3867623
End time: 15:18:06.3867623
duration: 00:00:00 (0ms)
Comparing byte arrays (32 bytes)
The same?: False
Start time: 15:18:06.3877624
End time: 15:18:06.3877624
duration: 00:00:00 (0ms)
FIRST BYTE DIFFERENT:
Comparing hex representations of the keys (64 characters)
k1: 2F5F587E5057C152F8A0F7CCE30ECDC0B26D45721E6FA538AE6AD0D31D478346
k2: 1F5F587E5057C152F8A0F7CCE30ECDC0B26D45721E6FA538AE6AD0D31D478346
The same?: False
Start time: 15:20:42.1843405
End time: 15:20:42.1843405
duration: 00:00:00 (0ms)
Comparing byte arrays (32 bytes)
The same?: False
Start time: 15:20:42.1853406
End time: 15:20:42.1853406
duration: 00:00:00 (0ms)我看不出在比较时间上有什么不同。据我所知,这是瞬间的。即使有几毫秒的差异,我是否认为网络响应时间的正常差异会抵消比较时间上的差异呢?
而且,在我的测试中,每次运行PBKDF2所花费的时间并不完全相同,即使参数相同。请参见以下4个PBKDF2以相同的参数运行,并且计算时间非常不同:
SALT: ndlD7w4CAW1EcoHCLxwhxg==
ITER: 100000
PASS: v/iFo8ZAjmG3q/9/8/oGwAWCcdY=
START: 10:16:59.2283073
END: 10:16:59.6813526
MS: 453.0453
SALT: ndlD7w4CAW1EcoHCLxwhxg==
ITER: 100000
PASS: v/iFo8ZAjmG3q/9/8/oGwAWCcdY=
START: 10:16:58.4052250
END: 10:16:58.8672712
MS: 462.0462
SALT: ndlD7w4CAW1EcoHCLxwhxg==
ITER: 100000
PASS: v/iFo8ZAjmG3q/9/8/oGwAWCcdY=
START: 10:16:57.6161461
END: 10:16:58.0771922
MS: 461.0461
SALT: ndlD7w4CAW1EcoHCLxwhxg==
ITER: 100000
PASS: v/iFo8ZAjmG3q/9/8/oGwAWCcdY=
START: 10:16:56.7020547
END: 10:16:57.1611006
MS: 459.0459如果您关注这种定时攻击,我的建议是做您的正常PBKDF2检查,并得到检查的结果做一个正常(非慢速)比较。然后生成500到3000之间的伪随机数(RN) (例如)。为RN迭代在随机数据上运行另一个PBKDF2。我认为,这会很好地随机化响应时间。有人对此有不同的想法吗?
注意:使用标准C#/.NET实现在i7处理器上完成的所有测试。
NOTE2:我假设我们在谈论/关注的是互联网登录,攻击者没有物理访问服务器的权限,无法以某种方式测量功率吸引。
https://crypto.stackexchange.com/questions/14648
复制相似问题