计时攻击
下面是我自己的理解:
引入
假设这样一种情况:一个服务器需要核实客户机传来的登录密码是否与数据库内部的密码相同,最简单的比较函数都容易想到:
def login(input):
later_password = input
now_num = 0
for i in range(len(first_password)):
if later_password[i] != first_password[i]:
return False
break
else:
now_num += 1
if now_num == len(first_password):
return True
这样的逐位比较传入字符的方式一定很快,但实际上也是不安全的:
在程序进行逐位比较的过程中,如果单独一位的密码相同,程序运行的时间比因为密码不同而报错的时间要多(逻辑结构更多一些)
这样造成的时间差返回给客户机,客户机就可以从中分析出哪些位的密码是正确的,哪些位的密码是错误的
也可以这样来理解:
当传入不同的字符串进行试探时,若所构造字符串与目标字符串从首字符起匹配的内容较长,则函数执行耗时较长;若匹配内容较短,则函数执行耗时较短;
执行时间的差异一定能够反映两个字符串的匹配度
攻击过程
构造一个包含所有可能成为目标密码的字符的字符表
逐位匹配:
比如password = “hello”
那么构造一个只包含小写字母的字符表
依次尝试"a",“b”,"c"等等,当匹配到"h"的时候判断时间较其他字符长
所以第一位选出为"h"
依次类推
直到最后一位爆破出来为"o",则代码结束
防御方法
一、
让服务器在返回给客户机密码是否正确之前的时间固定,就算实际运算了很短的时间也要等过完这段时间之后进行回复
二、
将传入的字符串(密码)与数据库内部的密码逐位进行异或;
判断异或结果是否为0(如果是0,1异或得到1;1,1或者0,0异或均得1)
所有位数的异或结果为0则密码正确
def constant(input,password):
if len(input) != len(password);
return False
for i in range(len(input)):
result = input[i] ^ password[i]
return result == 0
实际上这种情况下依旧可以进行爆破,可以得到目标字符串的长度
三、
执行hash函数,逐一比较hash函数过后的密文的每一位
import hashlib
总结
实际上,timing attack属于侧信道攻击
而侧信道攻击又有功耗分析
边信道攻击方法 主要集中在功耗攻击、电磁场攻击和时间攻击。其中功耗攻击是最强有力的手段之一,包括简单功耗分析攻击(SimplePower Analysis attacks,SPA)和差分功耗分析攻击(Differential Power Analysis attacks,DPA),与传统密码分析学相比,这些攻击手段攻击效果显著。