1、Convert hex to base64
题意:给出一个hex编码过的字符串,将它进行base64加密
解题关键:直接利用base64库函数实现
1 import base64 2 str1="49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d".decode("hex") 3 me = base64.b64encode(str1) 4 print me
2、Fixed XOR
题意:将两个16进制字符串进行异或
解题关键:将16进制字符串解码,对每个字符分别进行异或,最后编码成16进制即可。
1 #coding=utf-8 2 import base64 3 import re 4 #异或操作无论对什么数都是以二进制的形式实现,所以无所谓进制 5 #str1=long("1c0111001f010100061a024b53535009181c",16) 6 #str2=long("686974207468652062756c6c277320657965",16) 7 str1="1c0111001f010100061a024b53535009181c".decode('hex') 8 str2="686974207468652062756c6c277320657965".decode('hex') 9 str3=[] 10 for i in range(0,len(str1)): 11 str3+=[chr(ord(str1[i])^ord(str2[i]))] 12 str3="".join(str3) 13 print str3.encode('hex') 14 15 #str=str1^str2 16 #print hex(str) 17 #print str
3、Single-byte XOR cipher
题意:字符串被某个单字符加密过,找出这个字符
解题关键:1、字符所处的ASCII码范围为0-255,暴力搜索,得出字符串字母数量最多的即为解。
2、判断的方式还可以按照英文中各字母出现的频率计算。
法一:
1 #coding=utf-8 2 import re 3 str="1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736" 4 score=0 5 for i in range(0,129): 6 tmp=[] 7 for j in re.findall(".{2}",str):#任意两个字符的字符串 8 tmp += chr(i^int(j,16)) 9 tmpstr = "".join(tmp) 10 num=0 11 for j in range(0,len(tmpstr)): 12 if tmpstr[j]>='a'and tmpstr[j]<='z':#or tmpstr[j]>='A'and tmpstr[j]<='Z': 13 num+=1 14 if num>score: 15 #print tmpstr 16 score=num#用于更新用 17 ansstr=tmpstr 18 key=chr(i) 19 print key 20 print ansstr
法二:
1 #coding=utf-8 2 import re 3 def english_test(sentence): 4 score = 0 5 freqs = { 6 'a': 0.0651738, 'b': 0.0124248, 'c': 0.0217339, 7 'd': 0.0349835, 'e': 0.1041442, 'f': 0.0197881, 8 'g': 0.0158610, 'h': 0.0492888, 'i': 0.0558094, 9 'j': 0.0009033, 'k': 0.0050529, 'l': 0.0331490, 10 'm': 0.0202124, 'n': 0.0564513, 'o': 0.0596302, 11 'p': 0.0137645, 'q': 0.0008606, 'r': 0.0497563, 12 's': 0.0515760, 't': 0.0729357, 'u': 0.0225134, 13 'v': 0.0082903, 'w': 0.0171272, 'x': 0.0013692, 14 'y': 0.0145984, 'z': 0.0007836, ' ': 0.1918182} 15 for x in sentence.lower(): 16 if x in freqs: 17 score += freqs[x] 18 return score 19 20 str="1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736" 21 score=0 22 for i in range(0,129): 23 tmp=[] 24 for j in re.findall(".{2}",str):#任意两个字符的字符串 25 tmp += chr(i^int(j,16)) 26 tmpstr = "".join(tmp) 27 num=english_test(tmpstr) 28 if num>score: 29 #print tmpstr 30 score=num#用于更新用 31 ansstr=tmpstr 32 key=chr(i) 33 print key 34 print ansstr
4、 Detect single-character XOR
题意: 文本中有一个字符串被单字符加密过,找出这个字符串
解题关键:对file中所有的字符串进行暴力匹配字符,最终得到小写字母数量最多的字符串和秘钥字符即为解(以下进行异或匹配的时候,判断方式均可运用频率函数)
1 #coding=utf-8 2 import re 3 #with open("ex4.txt") as fp: 4 #wenben=[i for i in open("ex4.txt").readlines()] 5 wenben=[] 6 for i in open("ex4.txt","r").readlines(): 7 wenben+=[i.replace(" ","")] #序列相加 8 score=0 9 for k in wenben: 10 for i in range(0,129): 11 tmp=[] 12 for j in re.findall(".{2}",k):#任意两个字符的字符串 13 tmp += chr(i^int(j,16)) 14 tmpstr = "".join(tmp) 15 num=0 16 num=len(re.findall(r'[a-zA-Z ]',tmpstr))#一定注意不要落下空格 17 if num>score: 18 score=num#用于更新用 19 ansstr=tmpstr 20 c=k 21 key=chr(i) 22 print c 23 print key 24 print ansstr
5、Implement repeating-key XOR
题意:将某个字符串使用秘钥进行重复异或
解题关键: 将秘钥扩展,单字节异或即可,最后编码成16进制
1 import re 2 str1=re.findall('.{2}',"Burning 'em, if you ain't quick and nimble I go crazy when I hear a cymbal".encode('hex')) 3 str2=re.findall('.{2}',("ICE"*200).encode('hex')) 4 str3=[] 5 for i in range(0,len(str1)): 6 str3 +=[(chr(int(str1[i],16)^int(str2[i],16)))] 7 print "".join(str3).encode('hex')
1 import re 2 str1="Burning 'em, if you ain't quick and nimble I go crazy when I hear a cymbal" 3 str2="ICE"*200 4 str3=[] 5 for i in range(0,len(str1)): 6 str3 +=[(chr(ord(str1[i])^ord(str2[i])))] 7 print "".join(str3).encode('hex') 8 #for i in range(0,len(str1)): 9 # str3 +=[(hex(ord(str1[i])^ord(str2[i])))] 10 #print "".join(str3)
6、Break repeating-key XOR
题意:base64编码后的字符串使用某串key加密过,解出明文
解题关键:首先按照可能的keysize对密文进行分块,取前4个进行两两求汉明距离,若分块的长度等于keysize,则应具有最小的汉明距离,(字母之间的汉明距离小),得到keysize之后,对分块的第一位、第二位分别进行匹配,最终得到解。
法一:转化为hex求解
1 #coding:utf-8 2 import re 3 import base64 4 with open("ex6.txt","r") as fp: 5 wenben=[base64.b64decode(i) for i in fp.readlines()] 6 wenben="".join(wenben) 7 8 def english_test(sentence): 9 score = 0 10 freqs = { 11 'a': 0.0651738, 'b': 0.0124248, 'c': 0.0217339, 12 'd': 0.0349835, 'e': 0.1041442, 'f': 0.0197881, 13 'g': 0.0158610, 'h': 0.0492888, 'i': 0.0558094, 14 'j': 0.0009033, 'k': 0.0050529, 'l': 0.0331490, 15 'm': 0.0202124, 'n': 0.0564513, 'o': 0.0596302, 16 'p': 0.0137645, 'q': 0.0008606, 'r': 0.0497563, 17 's': 0.0515760, 't': 0.0729357, 'u': 0.0225134, 18 'v': 0.0082903, 'w': 0.0171272, 'x': 0.0013692, 19 'y': 0.0145984, 'z': 0.0007836, ' ': 0.1918182} 20 for x in sentence.lower(): 21 if x in freqs: 22 score += freqs[x] 23 return score 24 25 def hanming(x,y): 26 num=0 27 for i in range(0,len(x)): 28 t=ord(x[i])^ord(y[i]) 29 while t: 30 if t&1 : num+=1 31 t>>=1 32 return num 33 34 def thechar(st1): 35 score = 0 36 for i in range(0, 255): 37 tmp = [] 38 for j in range(0,len(st1)): # 任意两个字符的字符串 39 tmp += chr(i ^ int(st1[j],16)) 40 tmpstr = "".join(tmp) 41 42 #num=len(re.findall(r'[a-zA-Z ,.;?!:]',tmpstr)) #'[a-zA-Z ,.?!:;]' 43 num=english_test(tmpstr) 44 if num > score: 45 score = num # 用于更新用 46 key = chr(i) 47 #print key,score 48 return key 49 50 51 ans = [] 52 for i in range(1,41): 53 str1=[] 54 str2=[] 55 str3=[] 56 str4=[] 57 for j in range(0,i): str1+=[wenben[j]] 58 for j in range(i,2*i): str2+=[wenben[j]] 59 for j in range(2*i,3*i): str3+=[wenben[j]] 60 for j in range(3*i,4*i): str4+=[wenben[j]] 61 str1="".join(str1) 62 str2="".join(str2) 63 str3="".join(str3) 64 str4="".join(str4) 65 x1=float(hanming(str1,str2))/i 66 x2=float(hanming(str2,str3))/i 67 x3=float(hanming(str3,str4))/i 68 x4=float(hanming(str1,str4))/i 69 x5=float(hanming(str1,str3))/i 70 x6=float(hanming(str2,str4))/i 71 aa=(x1+x2+x3+x4+x5+x6)/6 72 ans+=[(i,aa)] 73 ans.sort(lambda x,y:cmp(x[1],y[1])) 74 for i in range(len(ans)): 75 print ans[i][0],ans[i][1] 76 #print len(wenben) 77 #print len(wenben)%29 78 wenben=wenben.encode('hex') 79 80 block=[re.findall(r'(.{2})',z) for z in re.findall(r'(.{58})',wenben)] 81 82 83 84 keyy = [] 85 for i in range(0,29): 86 tmp=[] 87 for j in range(0,len(block)): 88 tmp+=[block[j][i]] 89 keyy+=[thechar(tmp)] 90 keyy="".join(keyy) 91 92 print keyy 93 keyy=keyy*10000 94 95 wenben=wenben.decode('hex') 96 an=[] 97 for i in range(0,len(wenben)): 98 an+=[chr(ord(wenben[i])^ord(keyy[i]))] 99 an="".join(an) 100 print an
法二:直接对字符串进行求解:debug了两天,原来是正则表达式的.无法匹配换行符的原因,换了个写法就过了
1 #coding:utf-8 2 import re 3 import base64 4 with open("ex6.txt","r") as fp: 5 wenben=[base64.b64decode(i) for i in fp.readlines()] 6 print len(wenben[2]) 7 wenben="".join(wenben) 8 9 def english_test(sentence): 10 score = 0 11 freqs = { 12 'a': 0.0651738, 'b': 0.0124248, 'c': 0.0217339, 13 'd': 0.0349835, 'e': 0.1041442, 'f': 0.0197881, 14 'g': 0.0158610, 'h': 0.0492888, 'i': 0.0558094, 15 'j': 0.0009033, 'k': 0.0050529, 'l': 0.0331490, 16 'm': 0.0202124, 'n': 0.0564513, 'o': 0.0596302, 17 'p': 0.0137645, 'q': 0.0008606, 'r': 0.0497563, 18 's': 0.0515760, 't': 0.0729357, 'u': 0.0225134, 19 'v': 0.0082903, 'w': 0.0171272, 'x': 0.0013692, 20 'y': 0.0145984, 'z': 0.0007836, ' ': 0.1918182} 21 for x in sentence.lower(): 22 if x in freqs: 23 score += freqs[x] 24 return score 25 26 def hanming(x,y): 27 num=0 28 for i in range(0,len(x)): 29 t=ord(x[i])^ord(y[i]) 30 while t: 31 if t&1 : num+=1 32 t>>=1 33 return num 34 35 def thechar(st1): 36 score = 0 37 for i in range(0, 255): 38 tmp = [] 39 for j in range(0,len(st1)): # 任意两个字符的字符串 40 #print str1 41 tmp += chr(i ^ ord(st1[j])) 42 tmpstr = "".join(tmp) 43 #num=len(re.findall(r'[a-zA-Z ,.;?!:]',tmpstr)) #'[a-zA-Z ,.?!:;]' 44 num=english_test(tmpstr) 45 if num > score: 46 score = num # 用于更新用 47 key = chr(i) 48 #print key,score 49 return key 50 51 ans = [] 52 for i in range(1,41): 53 str1=[] 54 str2=[] 55 str3=[] 56 str4=[] 57 for j in range(0,i): str1+=[wenben[j]] 58 for j in range(i,2*i): str2+=[wenben[j]] 59 for j in range(2*i,3*i): str3+=[wenben[j]] 60 for j in range(3*i,4*i): str4+=[wenben[j]] 61 str1="".join(str1) 62 str2="".join(str2) 63 str3="".join(str3) 64 str4="".join(str4) 65 x1=float(hanming(str1,str2))/i 66 x2=float(hanming(str2,str3))/i 67 x3=float(hanming(str3,str4))/i 68 x4=float(hanming(str1,str4))/i 69 x5=float(hanming(str1,str3))/i 70 x6=float(hanming(str2,str4))/i 71 aa=(x1+x2+x3+x4+x5+x6)/6 72 ans+=[(i,aa)] 73 ans.sort(lambda x,y:cmp(x[1],y[1])) 74 for i in range(len(ans)): 75 print ans[i][0],ans[i][1] 76 #print len(wenben) 77 #print len(wenben)%29 78 #wenben=wenben.encode('hex') 79 #print wenben 80 #wenben=wenben.decode('utf-8') 81 block=re.findall(r'[sS]{29}',wenben) 82 #block=[wenben[i:i+29] for i in xrange(0,len(wenben),29)] 83 #for i in range(0,len(block)): 84 # block[i]=block[i] 85 b1=[] 86 print block 87 #print block[0][4].encode('hex') 88 print block[0] 89 print len(block[0]) 90 nn=0 91 for i in range(0,len(block)): 92 for j in range(0,len(block[i])): 93 nn+=1 94 print nn 95 96 print [z.encode('hex') for z in block[3]] 97 print block[3][28].encode('hex') 98 print len(block[3]) 99 print block[3][0].encode('hex') 100 print block[3] 101 #['37', '16', '06', '0c', '1a', '17', '41', '1d', '01', '52', '54', '30', '5f', '00', '20', '13', '0a', '05', '47', '4f', '12', '48', '08', '45', '4e', '65', '3e', '16', '09'] 102 103 keyy = [] 104 for i in range(0,29): 105 tmp=[] 106 for j in range(0,len(block)): 107 tmp+=block[j][i] 108 tmp="".join(tmp) 109 keyy+=thechar(tmp) 110 keyy="".join(keyy) 111 112 print keyy 113 keyy=keyy*10000 114 115 #wenben=wenben.decode('hex') 116 an=[] 117 for i in range(0,len(wenben)): 118 an+=[chr(ord(wenben[i])^ord(keyy[i]))] 119 an="".join(an) 120 print an
7、AES in ECB mode
题意:解密进行aes-128加密过的字符串
解题关键:利用pycrypto库,首先将秘钥编码,然后进行AES编码即可。
1 from Crypto.Cipher import AES 2 import base64,re 3 with open("ex7.txt","r") as fp: 4 C=[base64.b64decode(i.replace(" ","")) for i in fp.readlines()] 5 C="".join(C) 6 7 key = "YELLOW SUBMARINE" 8 cipher=AES.new(key,AES.MODE_ECB) 9 m= cipher.decrypt(C) 10 print m
8、Detect AES in ECB mode
题意:找出被ECB加密过的字符串
解题关键:将文本连接起来,以16字节分块,根据ECB的性质,相同的 16 字节明文经过加密后总会产生相同的 16 字节密文,若存在相同块,即可ECS编码
1 import re 2 with open("ex8.txt","r") as fp: 3 wenben=[i.replace(" ","") for i in fp.readlines()] 4 for ecb in wenben: 5 block =re.findall(".{16}",ecb) 6 if len(block)-len(set(block)): 7 print ecb