好像for a while ,Unix 系统上的登录实用程序仅在存在有效用户名时才计算哈希值;这打开了一个允许定时攻击的安全漏洞,因为用户可以通过生成哈希 key 进行比较所需的时间来判断何时找到用户名。
这对桌面应用程序有意义,但对 Web 应用程序也有意义吗?我倾向于这样做,但是这种修复有必要吗?
例如,在 Django 身份验证模块中:
class MyBackend(ModelBackend):
def authenticate(self, email=None, password=None):
try:
user = User.objects.get(email=email)
return user if user.check_password(password) else None
except User.DoesNotExist:
User().check_password(password) # is this line necessary?
return None
对于这种情况,额外的哈希计算是否有意义?如果我对 auth 调用使用速率限制,这是否会降低像这样的定时攻击的可能性?
最佳答案
原始定时攻击,Tenex攻击,与散列无关——它通过定位密码来工作,使其跨越页面边界,导致虚拟内存缓存未命中。攻击者可以尝试设置一系列密码,以便只有第一个字符在第一页中,并且当验证需要足够长的时间以发生缓存未命中时,它会知道第一个字符匹配。攻击者可以对密码中的每个字符重复此操作。
除非攻击者可以控制输入在内存中的细粒度定位,否则对密码的定时攻击不是问题,而是任何超线性 w.r.t 的 secret 检查算法。 secret 的长度(> = O( secret 长度))可能会泄露有关密码长度的信息。
如果您小心地比较密码中的所有字符而不考虑成功,那么您也可以击败攻击:
boolean match = true;
for (int i = 0; i < min(salted_from_db_length, salted_from_user_length); ++i) {
if (salted_from_db[i] != salted_from_user[i]) {
match = false;
//break; // Stopping early leaks info.
}
}
match = salted_from_db_length == salted_from_user_length && match;
您应该进行测试以确保编译器优化不会将时序漏洞放回您的代码中。
请注意,术语“定时攻击”也用于其他上下文,并且会影响 Web 应用程序。例如,当系统时钟用于构造 covert channel在两个不能共谋的进程之间——加载在两个不同来源的 javascript 可以通过使用间隔来检查时间并循环消耗处理器或不进行通信来建立低带宽 channel 。
关于security - 防止定时攻击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8030017/