import Crypto.Util.strxor as xo import libnum, codecs, numpy as np
defisChr(x): iford('a') <= x and x <= ord('z'): returnTrue iford('A') <= x and x <= ord('Z'): returnTrue returnFalse
definfer(index, pos): if msg[index, pos] != 0: return msg[index, pos] = ord(' ') for x inrange(len(c)): if x != index: msg[x][pos] = xo.strxor(c[x], c[index])[pos] ^ ord(' ')
dat = []
defgetSpace(): for index, x inenumerate(c): res = [xo.strxor(x, y) for y in c if x!=y] f = lambda pos: len(list(filter(isChr, [s[pos] for s in res]))) cnt = [f(pos) for pos inrange(len(x))] for pos inrange(len(x)): dat.append((f(pos), index, pos))
c = [codecs.decode(x.strip().encode(), 'hex') for x inopen('Problem.txt', 'r').readlines()]
msg = np.zeros([len(c), len(c[0])], dtype=int)
getSpace()
dat = sorted(dat)[::-1] for w, index, pos in dat: infer(index, pos)
print('\n'.join([''.join([chr(c) for c in x]) for x in msg]))
执行代码,得到的结果是:
1 2 3 4 5 6 7 8 9 10 11
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...
defknow(index, pos, ch): msg[index, pos] = ord(ch) for x inrange(len(c)): if x != index: msg[x][pos] = xo.strxor(c[x], c[index])[pos] ^ ord(ch)
know(10, 21, 'y') know(8, 14, 'n')
print('\n'.join([''.join([chr(c) for c in x]) for x in msg]))
结果得到:
1 2 3 4 5 6 7 8 9 10 11
Dear Friend, This time I u nderstood my mistake and u sed One time pad encryptio n scheme, I heard that it is the only encryption met hod that is mathematically proven to be not cracked ever if the key is kept se cure, Let Me know if you a gree with me to use this e ncryption scheme always...
我们成功恢复了明文!那么 key 也很好取得了:把 异或上 即可。
1 2 3 4
key = xo.strxor(c[0], ''.join([chr(c) for c in msg[0]]).encode()) print(key)
import Crypto.Util.strxor as xo import libnum, codecs, numpy as np
defisChr(x): iford('a') <= x and x <= ord('z'): returnTrue iford('A') <= x and x <= ord('Z'): returnTrue returnFalse
definfer(index, pos): if msg[index, pos] != 0: return msg[index, pos] = ord(' ') for x inrange(len(c)): if x != index: msg[x][pos] = xo.strxor(c[x], c[index])[pos] ^ ord(' ')
defknow(index, pos, ch): msg[index, pos] = ord(ch) for x inrange(len(c)): if x != index: msg[x][pos] = xo.strxor(c[x], c[index])[pos] ^ ord(ch)
dat = []
defgetSpace(): for index, x inenumerate(c): res = [xo.strxor(x, y) for y in c if x!=y] f = lambda pos: len(list(filter(isChr, [s[pos] for s in res]))) cnt = [f(pos) for pos inrange(len(x))] for pos inrange(len(x)): dat.append((f(pos), index, pos))
c = [codecs.decode(x.strip().encode(), 'hex') for x inopen('Problem.txt', 'r').readlines()]
msg = np.zeros([len(c), len(c[0])], dtype=int)
getSpace()
dat = sorted(dat)[::-1] for w, index, pos in dat: infer(index, pos)
know(10, 21, 'y') know(8, 14, 'n')
print('\n'.join([''.join([chr(c) for c in x]) for x in msg]))
key = xo.strxor(c[0], ''.join([chr(c) for c in msg[0]]).encode()) print(key)
from itertools import cycle import codecs, numpy as np import Crypto.Util.strxor as xo
salt="WeAreDe1taTeam" si=cycle(salt)
c = codecs.decode('49380d773440222d1b421b3060380c3f403c3844791b202651306721135b6229294a3c3222357e766b2f15561b35305e3c3b670e49382c295c6c170553577d3a2b791470406318315d753f03637f2b614a4f2e1c4f21027e227a4122757b446037786a7b0e37635024246d60136f7802543e4d36265c3e035a725c6322700d626b345d1d6464283a016f35714d434124281b607d315f66212d671428026a4f4f79657e34153f3467097e4e135f187a21767f02125b375563517a3742597b6c394e78742c4a725069606576777c314429264f6e330d7530453f22537f5e3034560d22146831456b1b72725f30676d0d5c71617d48753e26667e2f7a334c731c22630a242c7140457a42324629064441036c7e646208630e745531436b7c51743a36674c4f352a5575407b767a5c747176016c0676386e403a2b42356a727a04662b4446375f36265f3f124b724c6e346544706277641025063420016629225b43432428036f29341a2338627c47650b264c477c653a67043e6766152a485c7f33617264780656537e5468143f305f4537722352303c3d4379043d69797e6f3922527b24536e310d653d4c33696c635474637d0326516f745e610d773340306621105a7361654e3e392970687c2e335f3015677d4b3a724a4659767c2f5b7c16055a126820306c14315d6b59224a27311f747f336f4d5974321a22507b22705a226c6d446a37375761423a2b5c29247163046d7e47032244377508300751727126326f117f7a38670c2b23203d4f27046a5c5e1532601126292f577776606f0c6d0126474b2a73737a41316362146e581d7c1228717664091c', 'hex')
a = [r ^ ord(next(si)) for r in c] # a[i] = m[i] ^ k[i]
defdiv(sz): ret = [''.join([chr(ch) for ch in a[i*sz : (i+1)*sz]]).encode() for i inrange(len(a)//sz)] # if len(a) % sz != 0: # ret.append(a[len(a)//sz*sz:]) print('\n'.join(map(lambda x:codecs.encode(x, 'hex').decode(), ret))) return ret
➜ workspace python3 work.py > out.txt ➜ workspace python3 mtp.py In faith I do not love thee wi th mine eyes,For they in thee a thousand errors note;But `ti s my heart that loves what the y despise,Who in despite of vi ew is pleased to dote.Nor are mine ears with thy tongue`s tu ne delighted;Nor tender feelin g to base touches prone,Nor ta ste, nor smell, desire to be i nvitedTo any sensual feast wit h thee alone.But my five wits, nor my five senses canDissuad e one foolish heart from servi ng thee,Who leaves unswayed th e likeness of a man,Thy proud heart`s slave and vassal wretc h to be.Only my plague thus fa r I count my gain,That she tha t makes me sin awards me pain. b'W3lc0m3tOjo1nu55un1ojOt3m0cl3W'
在已知常数A,B,M的前提下,若能捕获到线性同余生成器的一个输出,则可以恢复出状态,并通过递 推式预测之后产生的所有随机数。 Xn+1≡Axn+B(mod M) Xn≡(xn+1-B)A^-1(mod M) 对于C语言标准库中的rand()函数,即为 Xn =(xn+1-12345)×1857678181(mod 2147483648)
在已知常数M但未知A,B的条件下,若能捕获到线性同余生成器的连续两个输出,则可以建立一个 关于A,B的同余方程: X(i+1) ≡Axi+B(mod M) 获取2个同余方程,可以建立一个方程组,解方程组即可得到A,B: x(i+1) ≡Axi+B (mod M) x(j+1)≡Axj+B (mod M)
defIP(block): result = [] for i inrange(len(IP_table)): result.append(block[IP_table[i]-1]) return result
defFP(block): result = [] for i inrange(len(FP_table)): result.append(block[FP_table[i]-1]) return result
总体结构:
1 2 3 4 5 6 7 8 9 10 11
# Initial permutation m = IP(m) # divide the block into two 32-bit halves Li, Ri = m[:32], m[32:] # 16 rounds for i inrange(16): Li, Ri = Ri, BlockXor(Li, Feistel(Ri, subkey[i])) # merge the two divided half block which is 32-bit into one 64-bit block m = Ri + Li # There is a need to change order of the final two halves # Final permutation m = FP(m)
轮函数的具体运算如下:
先通过Expansion将32比特输入扩展为48 比特
再与48比特的子密钥混合作异或运算
然后48比特分别分为8组,每组6比特,经,过S盒替换,输出8组4比特,即32比特
最后对这32比特进行移位置换P 密钥扩展的具体运算如下:
ㅤ
先通过PC-1置换去除64比特密钥中的校验位
将56比特的密钥分成左右28比特两半
连续16轮运算,每一轮分别先对左右两半循环移位,再经过PC-2置换生成一个48比特的子密钥
最终得到16组48比特的字密钥,用于加解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14
subkey = [] iflen(bkey) == 64: # PC-1 bkey = PC_1(bkey) eliflen(bkey) # 56: raise ValueError("key must be 56-bit or 64-bit in length") # divide the block into two halves Ci, Di = bkey[: 28], bkey[28:] for i inrange(16): # Left Rotation Ci, Di = LR(Ci, Di, i) # PC-2 subkey.append(PC_2(Ci + Di)) return subkey # ok
@staticmethod defkey_expansion(k, r): # fips-197 Figure 11 k = list(k) # in case k is bytes Nk = len(k) // 4 subkeys = [k[i:i + 4] for i inrange(0, 4 * Nk, 4)]
i = Nk while i < 4 * (r + 1): t = subkeys[i - 1] if i % Nk == 0: tt = AES.sub_word(AES.rot_word(t)) t = [tt[0] ^ AES.Rcon[i // Nk]] + tt[1:] elif Nk > 6and i % Nk == 4: t = AES.sub_word(t) subkeys.append(AES.word_xor(subkeys[i - Nk], t)) i += 1 return subkeys