考虑登录 API入口点,该入口点获取用户名和密码。
密码是安全的哈希和盐渍,如果用户名不存在或密码不正确,我们会按照正确的做法返回相同的回复。
def verify_user(session, username, password):
user = session.query(Users.username == 'username').one()
stored_hash = user.password_hash if user is not None else 'some-dommy-hash'
return verify_password(password=password, hash=stored_hash)
请注意,我们还会尝试确保两个控制流都约相同的工作量,因此应 相同的时间。
但关于和 应该让我担心。
假设在数据库中查找和未查找用户花费相同的时间是否安全?我可以假设散列相同的虚拟散列不会被缓存吗?
我真正想要的是一种类似的方式:
def constant_time_verify_user(time, session, username, password):
with constant_time(time):
ans = verify_user(session, username, password)
return ans
其中constant_time
就像超时一样,在某种意义上它将完全一段时间。
所以我的问题:是否有一个完善的做法,或者有助于掩盖手术可能花费的时间的图书馆,以防止基于时间的攻击?
答案 0 :(得分:2)
我明白你真正担心的是什么。您不希望其他人知道用户是否存在。
在单线程结构下,它似乎不容易实现。但是,如果您可以接受使用多个线程,那么这是可能的。
您可以将函数包装到一个线程中并为其设置合理的超时。如果线程在超出超时之前返回,则再多睡一次。
由于我通常构建异步Web服务器,因此我更容易实现它。
async def constant_time_verify_user(time, session, username, password):
start_time = _time.time()
try:
ans = await asyncio.wait_for(verify_user(session, username, password), timeout=time)
await asyncio.sleep(time + start_time - _time.time())
return ans
except (asyncio.TimeoutError, asyncio.CancelledError):
return "Exceed maximum execute time!"