时差攻击

今天学习FastAPI时,细致了解了一下时差攻击。

时差攻击

什么是时差攻击?

假设攻击者试图猜出用户名与密码。

他们发送用户名为 johndoe,密码为 love123 的请求。

然后,Python 代码执行如下操作:

1
2
if "johndoe" == "stanleyjobson" and "love123" == "swordfish":
...

但就在 Python 比较完 johndoe 的第一个字母 j 与 stanleyjobson 的 s 时,Python 就已经知道这两个字符串不相同了,它会这么想,没必要浪费更多时间执行剩余字母的对比计算了。应用立刻就会返回错误的用户或密码。

但接下来,攻击者继续尝试 stanleyjobsox 和 密码 love123。

应用代码会执行类似下面的操作:

1
2
if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
...

此时,Python 要对比 stanleyjobsox 与 stanleyjobson 中的 stanleyjobso,才能知道这两个字符串不一样。因此会多花费几微秒来返回错误的用户或密码。

反应时间对攻击者的帮助

通过服务器花费了更多微秒才发送错误的用户或密码响应,攻击者会知道猜对了一些内容,起码开头字母是正确的。

然后,他们就可以放弃 johndoe,再用类似 stanleyjobsox 的内容进行尝试。

专业攻击

当然,攻击者不用手动操作,而是编写每秒能执行成千上万次测试的攻击程序,每次都会找到更多正确字符。

但是,攻击者利用时间差,就能在几分钟或几小时内,以这种方式猜出正确的用户名和密码。

使用 secrets.compare_digest() 修补

在此,代码中使用了 secrets.compare_digest()。

简单的说,它使用相同的时间对比 stanleyjobsox 和 stanleyjobson,还有 johndoe 和 stanleyjobson。对比密码时也一样。

在代码中使用 secrets.compare_digest() ,就可以安全地防御全面攻击了。

1
2
3
4
5
6
7
8
9
10
current_username_bytes = credentials.username.encode("utf8")
correct_username_bytes = b"stanleyjobson"
is_correct_username = secrets.compare_digest(
current_username_bytes, correct_username_bytes
)
current_password_bytes = credentials.password.encode("utf8")
correct_password_bytes = b"swordfish"
is_correct_password = secrets.compare_digest(
current_password_bytes, correct_password_bytes
)
Notice: 正常情况下,这里会有一个基于utteranc.es的留言系统,如果看不到,可能要想想办法才能看到。

Powered by Hexo and Hexo-theme-hiker

Copyright © 2012 - 2025 tiaobug.com All Rights Reserved.

鲁ICP备2024124237号-1