Python时序攻击密码破解器最后一位错误的原因及优化
时序攻击破解密码的问题与解决方案
1. 为何最后一位数字经常不正确?
因为验证最后一位时,无论该位正确与否,check_password的执行耗时完全一致:
- 当最后一位错误时,函数会逐位执行完所有4次
time.sleep(0.1),在最后一次sleep后判断字符不匹配,返回False; - 当最后一位正确时,函数同样执行完所有4次sleep,循环结束后返回True。
两者的耗时没有可区分的差异,导致程序无法通过时长判断最后一位的正确性。
而前面的位数可以通过耗时区分:例如验证第一位时,错误字符只会触发1次sleep就返回False,正确字符会触发至少2次sleep(继续验证第二位),耗时差异明显。
2. 如何提升计时测量准确性并确保破解正确?
可以从以下几个方面优化:
(1)多次测量取平均耗时
系统调度的随机波动会影响单次计时的准确性,对每个候选数字重复执行多次验证,计算平均耗时,能更真实反映实际耗时:
import time real_password = "7090" def check_password(password): # Don't change if len(password) != len(real_password): return False for x, y in zip(password, real_password): time.sleep(0.1) # Simulates the wait time of the safe's mechanism if int(x) != int(y): return False return True def crack_password(): password = ["0"] * len(real_password) repeat_times = 5 # 重复测量次数 for i in range(len(real_password)-1): # 先破解前n-1位 max_avg_time = 0 correct_digit = 0 for digit in range(10): password[i] = str(digit) total_time = 0 for _ in range(repeat_times): start_time = time.perf_counter() check_password("".join(password)) end_time = time.perf_counter() total_time += end_time - start_time avg_time = total_time / repeat_times if avg_time > max_avg_time: max_avg_time = avg_time correct_digit = digit password[i] = str(correct_digit) # 特殊处理最后一位:直接验证返回值 for digit in range(10): password[-1] = str(digit) if check_password("".join(password)): return "".join(password) return "".join(password) print(crack_password())
(2)增大sleep时长
适当增大check_password中的time.sleep(0.1)时长(比如改为0.5),可以放大正确与错误字符的耗时差异,减少相对误差,让计时结果更易区分。
(3)针对最后一位的特殊处理
当前面n-1位都确定正确后,直接利用check_password的返回值判断最后一位:此时正确的最后一位会让函数返回True,错误的返回False,无需依赖计时,彻底解决最后一位的识别问题。
(4)减少系统干扰
在运行破解程序时,尽量关闭其他占用CPU或IO的程序,避免系统调度干扰计时精度。
内容的提问来源于stack exchange,提问作者r0tten_appl3
相关产品推荐
相关产品推荐

