key
异或不同的明文
。而MTP是用同一个key
去异或多个明文。
OTP是无条件安全的:即使攻击者拥有无限的计算资源,都不可能破译OTP加密的密文。探索在使用一次一密的方法加密时,密钥被重复使用时的已知密文攻击方法。
正因为MTP的特性我们可以通过数学公式简化整个攻击过程,我们知道同一个内容的异或等于0,任何数和0异或都等于本身
所以当密文C1异或密文C2,按照MTP加密方式就可以数学等效为:(明文M1异或密钥key)异或(明文M2异或密钥key)即可等效为明文M1异或明文M2(因为key相同,异或之后为0,而任何与0的异或等于本身)
所以攻击者如果截获了足够多的密文,就有可能推断出明文、进而拿到密钥。
而ASCII表中有个比较特殊的符号,也就是空格,空格在ASCII编码中是32,也就是0x20,而小写字母异或空格,会得到对应的大写字母;大写字母异或空格,会得到小写字母,正因为这个特性,我们就可以破解出密文的内容。
所以举一反三如果两个明文异或得到的是一个英文字母,那么是不是他大概率异或了一个空格,所以公式可以做如下变形(M为明文col为第几位,所以知道某个字符串的某一位是空格,我们就可以恢复出所有明文在这一列的值。)
所以假如有一串16进制密文是:
25030206463d3d393131555f7f1d061d4052111a19544e2e5d54
0f020606150f203f307f5c0a7f24070747130e16545000035d54
1203075429152a7020365c167f390f1013170b1006481e13144e
0f4610170e1e2235787f7853372c0f065752111b15454e0e0901
081543000e1e6f3f3a3348533a270d064a02111a1b5f4e0a1855
0909075412132e247436425332281a1c561f04071d520f0b1158
4116111b101e2170203011113a69001b47520601155205021901
041006064612297020375453342c17545a01451811411a470e44
021311114a5b0335207f7c167f22001b44520c15544801125d40
06140611460c26243c7f5c167f3d015446010053005907145d44
0f05110d160f263f3a7f4210372c03111313090415481d49530f
ASCII是:
....S....N.U.....A..M.N... ...Ro..I...I....SE....P.I. .E..H...IN..H...........TU ..A.H.R.....E....P......E. ...RT...E...M....M....A.L. d...V..I..DNEt........K.DU .......I....K..I.ST...TiS. .....f...N.I........M.O... .........N.I...I.S.I..I... ....P....N.OH...SA....Sg..
我们就可以写脚本进行破译
import Crypto.Util.strxor asxo
import libnum, codecs, numpyasnp
defzifu_check(x):
iford('a') <=xandx<=ord('z'): returnTrue
iford('A') <=xandx<=ord('Z'): returnTrue
returnFalse
deftext(index, pos):
ifinput_text[index, pos] !=0:
return
input_text[index, pos] =ord(' ')
forxinrange(len(c)):
ifx!=index:
input_text[x][pos] =xo.strxor(c[x], c[index])[pos] ^ord(' ')
dat= []
defSC():
forindex, xinenumerate(c):
res= [xo.strxor(x, y) foryincifx!=y]
f=lambdapos: len(list(filter(zifu_check, [s[pos] forsinres])))
cnt= [f(pos) forposinrange(len(x))]
forposinrange(len(x)):
dat.append((f(pos), index, pos))
c= [codecs.decode(x.strip().encode(), 'hex') forxinopen('re.txt', 'r').readlines()]
input_text=np.zeros([len(c), len(c[0])], dtype=int)
SC()
dat=sorted(dat)[::-1]
forw, index, posindat:
text(index, pos)
print('n'.join([''.join([chr(c) forcinx]) forxininput_text]))
得到
Dear Friend, T%is tim< I u nderstood my m$stake 8nd u sed One time p,d encr ptio n scheme, I he,rd tha- it is the only en.ryptio7 met hod that is ma9hemati:ally proven to be #ot cra:ked ever if the ke4 is ke)t se cure, Let Me k#ow if ou a gree with me t" use t1is e ncryption sche e alwa s...
除了有些小细节需要修正的,但是基本上是可读的状态了
原文始发于微信公众号(由由学习吧):多次加密攻击
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论