week1
python
import binascii
ciphertexts = [
"315c4eeaa8b5f8aaf9174145bf43e1784b8fa00dc71d885a804e5ee9fa40b16349c146fb778cdf2d3aff021dfff5b403b510d0d0455468aeb98622b137dae857553ccd8883a7bc37520e06e515d22c954eba5025b8cc57ee59418ce7dc6bc41556bdb36bbca3e8774301fbcaa3b83b220809560987815f65286764703de0f3d524400a19b159610b11ef3e",
"234c02ecbbfbafa3ed18510abd11fa724fcda2018a1a8342cf064bbde548b12b07df44ba7191d9606ef4081ffde5ad46a5069d9f7f543bedb9c861bf29c7e205132eda9382b0bc2c5c4b45f919cf3a9f1cb74151f6d551f4480c82b2cb24cc5b028aa76eb7b4ab24171ab3cdadb8356f",
"32510ba9a7b2bba9b8005d43a304b5714cc0bb0c8a34884dd91304b8ad40b62b07df44ba6e9d8a2368e51d04e0e7b207b70b9b8261112bacb6c866a232dfe257527dc29398f5f3251a0d47e503c66e935de81230b59b7afb5f41afa8d661cb",
"32510ba9aab2a8a4fd06414fb517b5605cc0aa0dc91a8908c2064ba8ad5ea06a029056f47a8ad3306ef5021eafe1ac01a81197847a5c68a1b78769a37bc8f4575432c198ccb4ef63590256e305cd3a9544ee4160ead45aef520489e7da7d835402bca670bda8eb775200b8dabbba246b130f040d8ec6447e2c767f3d30ed81ea2e4c1404e1315a1010e7229be6636aaa",
"3f561ba9adb4b6ebec54424ba317b564418fac0dd35f8c08d31a1fe9e24fe56808c213f17c81d9607cee021dafe1e001b21ade877a5e68bea88d61b93ac5ee0d562e8e9582f5ef375f0a4ae20ed86e935de81230b59b73fb4302cd95d770c65b40aaa065f2a5e33a5a0bb5dcaba43722130f042f8ec85b7c2070",
"32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd2061bbde24eb76a19d84aba34d8de287be84d07e7e9a30ee714979c7e1123a8bd9822a33ecaf512472e8e8f8db3f9635c1949e640c621854eba0d79eccf52ff111284b4cc61d11902aebc66f2b2e436434eacc0aba938220b084800c2ca4e693522643573b2c4ce35050b0cf774201f0fe52ac9f26d71b6cf61a711cc229f77ace7aa88a2f19983122b11be87a59c355d25f8e4",
"32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd90f1fa6ea5ba47b01c909ba7696cf606ef40c04afe1ac0aa8148dd066592ded9f8774b529c7ea125d298e8883f5e9305f4b44f915cb2bd05af51373fd9b4af511039fa2d96f83414aaaf261bda2e97b170fb5cce2a53e675c154c0d9681596934777e2275b381ce2e40582afe67650b13e72287ff2270abcf73bb028932836fbdecfecee0a3b894473c1bbeb6b4913a536ce4f9b13f1efff71ea313c8661dd9a4ce",
"315c4eeaa8b5f8bffd11155ea506b56041c6a00c8a08854dd21a4bbde54ce56801d943ba708b8a3574f40c00fff9e00fa1439fd0654327a3bfc860b92f89ee04132ecb9298f5fd2d5e4b45e40ecc3b9d59e9417df7c95bba410e9aa2ca24c5474da2f276baa3ac325918b2daada43d6712150441c2e04f6565517f317da9d3",
"271946f9bbb2aeadec111841a81abc300ecaa01bd8069d5cc91005e9fe4aad6e04d513e96d99de2569bc5e50eeeca709b50a8a987f4264edb6896fb537d0a716132ddc938fb0f836480e06ed0fcd6e9759f40462f9cf57f4564186a2c1778f1543efa270bda5e933421cbe88a4a52222190f471e9bd15f652b653b7071aec59a2705081ffe72651d08f822c9ed6d76e48b63ab15d0208573a7eef027",
"466d06ece998b7a2fb1d464fed2ced7641ddaa3cc31c9941cf110abbf409ed39598005b3399ccfafb61d0315fca0a314be138a9f32503bedac8067f03adbf3575c3b8edc9ba7f537530541ab0f9f3cd04ff50d66f1d559ba520e89a2cb2a83",
"32510ba9babebbbefd001547a810e67149caee11d945cd7fc81a05e9f85aac650e9052ba6a8cd8257bf14d13e6f0a803b54fde9e77472dbff89d71b57bddef121336cb85ccb8f3315f4b52e301d16e9f52f904",
]
target = "32510ba9babebbbefd001547a810e67149caee11d945cd7fc81a05e9f85aac650e9052ba6a8cd8257bf14d13e6f0a803b54fde9e77472dbff89d71b57bddef121336cb85ccb8f3315f4b52e301d16e9f52f904"
length = len(ciphertexts)
# 16进制数字转换为asscii码对应字符
ciphertexts = [binascii.unhexlify(x) for x in ciphertexts]
# 这个方法可以直接对十六进制串进行异或操作
def strxor(a, b): # xor two strings of different lengths
return "".join([chr(x ^ y) for x, y in zip(a, b)])
# 对字符串里每个字符依次做异或操作,因此使用之前必须把要进行操作的字符串划分成一个一个的形式
# 这里本来相用第一种方法,但是获取的key好像无法完成转换成数字形式就放弃了
def stror1(a, b):
if len(a) > len(b):
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
else:
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])
def find_letter(s):
#返回给定字符串中给定字母的位置
position = []
for index in range(len(s)):
#考虑到空格异或为0的情况可能较多
if (s[index] >= 'A' and s[index] <= 'Z') or (s[index] >= 'a' and s[index] <= 'z') or s[index] == chr(0):
# space_counts[index] += 1
position.append(index)
return position
# 计算空格位置的可能性
def space_possibility(s):
space_new = []
for position in range(400):
count = 0
for idx_i in range(length - 1):
if position in s[idx_i]:
count += 1
if count > 7: # 如果异或后字母出现次数大于7次,认为明文中此处为空格
space_new.append(position)
return space_new
# 找到可能是空格符的位置
def find_space(ciphertexts):
space_possib = [] # 用于保存可能是空格符的位置
# 使用双重循环实现字符串两两异或
for ciphertext_i in ciphertexts:
space = [] # 用于保存可能是空格符的位置
for ciphertext_j in ciphertexts:
# 不和自己做异或
if ciphertext_i == ciphertext_j:
continue
xor_res = strxor(ciphertext_i, ciphertext_j)
# 记录每一条明文中可能空格符的位置
space.append(find_letter(xor_res))
# 对空格位置做可能性判断
space_possib.append(space_possibility(space))
return space_possib
#计算获得对应密钥Key
def cal_key(cipher):
space_possib = find_space(cipher)
key = [0] * 200 #存放key
for cipher_idx in range(length):
for position in range(len(space_possib[cipher_idx])):
idx = space_possib[cipher_idx][position] #十六进制,用2位表示
a = cipher[cipher_idx][idx]
key[space_possib[cipher_idx][position]] = a ^ ord(" ") # 计算密钥,获得结果十进制(ascii码)
key_str = "" #空串用于存放密钥
for k in key:
key_str += chr(k)#转化为
return key_str #获得密钥串
if __name__ == '__main__':
# space_possib = find_space(ciphertexts)
key = cal_key(ciphertexts)
result = ""
f = ''.join([chr(int(d, 16)) for d in [target[i:i + 2] for i in range(0, len(target), 2)]])
for letter in stror1(f, key):
result += letter
print(result)
PA1
python
# _*_ coding:utf-8 _*_
"""
@author km
@time: 2019/10/18 9:00
"""
# 类维吉尼亚密码破解(使用字节级XOR运算)
def findindexkey(subarr):
"""找出将密文subarr解密成可见字符的所有可能密钥值"""
# 可见字符范围:ASCII 32-125(空格到~)
visiable_chars = [chr(x) for x in range(32, 126)]
ans_keys = list(range(0x00, 0xFF)) # 所有可能的密钥值(0-255)
for key in list(ans_keys): # 遍历所有可能的密钥
for s in subarr:
# 解密后字符不在可见范围内,则排除该密钥
if chr(s ^ key) not in visiable_chars:
ans_keys.remove(key)
break
return ans_keys
# 密文(十六进制字符串)
strmi = 'F96DE8C227A259C87EE1DA2AED57C93FE5DA36ED4EC87EF2C63AAE5B9A7EFFD673BE4ACF7BE8923C\
AB1ECE7AF2DA3DA44FCF7AE29235A24C963FF0DF3CA3599A70E5DA36BF1ECE77F8DC34BE129A6CF4D126BF\
5B9A7CFEDF3EB850D37CF0C63AA2509A76FF9227A55B9A6FE3D720A850D97AB1DD35ED5FCE6BF0D138A84C\
C931B1F121B44ECE70F6C032BD56C33FF9D320ED5CDF7AFF9226BE5BDE3FF7DD21ED56CF71F5C036A94D96\
3FF8D473A351CE3FE5DA3CB84DDB71F5C17FED51DC3FE8D732BF4D963FF3C727ED4AC87EF5DB27A451D47E\
FD9230BF47CA6BFEC12ABE4ADF72E29224A84CDF3FF5D720A459D47AF59232A35A9A7AE7D33FB85FCE7AF5\
923AA31EDB3FF7D33ABF52C33FF0D673A551D93FFCD33DA35BC831B1F43CBF1EDF67F0DF23A15B963FE5DA\
36ED68D378F4DC36BF5B9A7AFFD121B44ECE76FEDC73BE5DD27AFCD773BA5FC93FE5DA3CB859D26BB1C63C\
ED5CDF3FE2D730B84CDF3FF7DD21ED5ADF7CF0D636BE1EDB79E5D721ED57CE3FE6D320ED57D469F4DC27A8\
5A963FF3C727ED49DF3FFFDD24ED55D470E69E73AC50DE3FE5DA3ABE1EDF67F4C030A44DDF3FF5D73EA250\
C96BE3D327A84D963FE5DA32B91ED36BB1D132A31ED87AB1D021A255DF71B1C436BF479A7AF0C13AA14794'
# 将十六进制密文转换为字节数组(每个元素为十进制值)
arr = []
for x in range(0, len(strmi), 2):
arr.append(int(strmi[x:x+2], 16))
# 枚举可能的密钥长度(1-14)
for keylen in range(1, 14):
for index in range(keylen): # 对密钥的每个位置进行测试
# 提取由同一密钥字节加密的密文片段(每隔keylen取一个)
subarr = arr[index::keylen]
ans_keys = findindexkey(subarr)
print(f'keylen={keylen}, index={index}, keys={ans_keys}')
if ans_keys: # 若存在可能的密钥,尝试解密第一个字符
ch = [chr(key ^ subarr[0]) for key in ans_keys]
print(ch)
print('###############')
import string
def findindexkey2(subarr):
"""更严格的密钥筛选:仅允许英文、数字、逗号、句号和空格"""
test_chars = string.ascii_letters + string.digits + ',.' + ' '
ans_keys = list(range(0x00, 0xFF)) # 所有可能的密钥值(0-255)
for key in list(ans_keys):
for s in subarr:
if chr(s ^ key) not in test_chars:
ans_keys.remove(key)
break
return ans_keys
# 确定密钥长度为7后,提取完整密钥
vigenerekeys = []
for index in range(7):
subarr = arr[index::7] # 按密钥长度7分组
vigenerekeys.append(findindexkey2(subarr))
print(vigenerekeys) # 输出密钥:[[186], [31], [145], [178], [83], [205], [62]]
print("#########")
# 解密密文
ming = ''
for i in range(len(arr)):
# 循环使用密钥的每个字节
key = vigenerekeys[i % 7][0]
ming += chr(arr[i] ^ key)
print(ming)
set1
1
python
# _*_ coding:utf-8 _*_
"""
@author km
@time: 2019/10/18 9:01
"""
import base64
import binascii
def hex_to_base64(hex_string):
# 先将十六进制字符串转换为字节流,再进行Base64编码
hex_bytes = binascii.unhexlify(hex_string)
# 编码后转换为字符串返回
return base64.b64encode(hex_bytes).decode('utf-8')
string = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"
print(hex_to_base64(string))
2
python
# _*_ coding:utf-8 _*_
"""
@author km
@time: 2019/10/18 9:08
"""
import binascii
def xor_strings(xs, ys):
"""对两个字节流进行XOR运算,返回结果字节流"""
return bytes(x ^ y for x, y in zip(xs, ys))
if __name__ == '__main__':
string1 = '1c0111001f010100061a024b53535009181c'
string2 = '686974207468652062756c6c277320657965'
# 将十六进制字符串转换为字节流(Python 3推荐方式)
hex_bytes1 = binascii.unhexlify(string1)
hex_bytes2 = binascii.unhexlify(string2)
# 执行XOR运算并转换为十六进制字符串
result_bytes = xor_strings(hex_bytes1, hex_bytes2)
result = binascii.hexlify(result_bytes).decode('utf-8')
print(result)
3
python
#coding=utf-8
import re
# 避免使用关键字作为变量名,改为hex_str
hex_str = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"
max_score = 0 # 记录最大匹配分数
best_ans = "" # 记录最佳解密结果
best_key = "" # 记录最佳密钥
for i in range(0, 129):
tmp = []
# 遍历十六进制字符串中的每两个字符(一个字节)
for j in re.findall(".{2}", hex_str):
# 解密:当前密钥与十六进制值异或,转换为字符
tmp.append(chr(i ^ int(j, 16)))
tmp_str = "".join(tmp)
# 统计小写字母数量作为评分标准
current_score = 0
for char in tmp_str:
if 'a' <= char <= 'z':
current_score += 1
# 更新最佳结果
if current_score > max_score:
max_score = current_score
best_ans = tmp_str
best_key = chr(i)
# Python 3中print为函数,使用括号
print(best_key)
print(best_ans)
4
python
#coding=utf-8
import re
# 使用上下文管理器安全读取文件,兼容Python 3
wenben = []
with open("4.txt", "r") as f:
for line in f.readlines():
wenben.append(line.replace("\n", "")) # 移除换行符并添加到列表
max_score = 0 # 记录最大匹配分数
best_ans = "" # 最佳解密结果
best_key = "" # 最佳密钥
best_c = "" # 最佳密文
for k in wenben:
for i in range(0, 129):
tmp = []
# 遍历每个十六进制字节
for j in re.findall(".{2}", k):
# 解密:当前密钥与十六进制值异或
tmp.append(chr(i ^ int(j, 16)))
tmp_str = "".join(tmp)
# 统计字母和空格的数量作为评分标准
current_score = len(re.findall(r'[a-zA-Z ]', tmp_str))
# 更新最佳结果
if current_score > max_score:
max_score = current_score
best_ans = tmp_str
best_c = k
best_key = chr(i)
# Python 3的print函数语法
print(best_c)
print(best_key)
print(best_ans)
5
python
# -*- coding: utf-8 -*-
def xor_repeat_key(key, string):
key_len = len(key)
str_result = ''
for index, ch in enumerate(string):
n = index % key_len # 循环使用密钥
# 对每个字符进行XOR运算
b = chr(ord(key[n]) ^ ord(ch))
str_result += b
return str_result
def main():
string1 = 'Burning \'em, if you ain\'t quick and nimble\nI go crazy when I hear a cymbal'
key = 'ICE'
# 处理十六进制编码并修正Python 3语法
encrypted = xor_repeat_key(key, string1)
# 将加密结果转换为十六进制字符串(Python 3方式)
hex_result = encrypted.encode('utf-8').hex()
print(hex_result)
if __name__ == '__main__':
main()
6
python
#coding:utf-8
import re
import base64
import binascii
# 读取并解码Base64密文
with open("6.txt", "r") as fp:
# 读取每一行并解码,拼接为字节流
wenben = b"".join([base64.b64decode(line.strip()) for line in fp.readlines()])
def english_test(sentence):
"""通过字母频率判断字符串是否为英文文本"""
score = 0
# 英文字母及空格的出现频率
freqs = {
'a': 0.0651738, 'b': 0.0124248, 'c': 0.0217339,
'd': 0.0349835, 'e': 0.1041442, 'f': 0.0197881,
'g': 0.0158610, 'h': 0.0492888, 'i': 0.0558094,
'j': 0.0009033, 'k': 0.0050529, 'l': 0.0331490,
'm': 0.0202124, 'n': 0.0564513, 'o': 0.0596302,
'p': 0.0137645, 'q': 0.0008606, 'r': 0.0497563,
's': 0.0515760, 't': 0.0729357, 'u': 0.0225134,
'v': 0.0082903, 'w': 0.0171272, 'x': 0.0013692,
'y': 0.0145984, 'z': 0.0007836, ' ': 0.1918182}
for x in sentence.lower():
if x in freqs:
score += freqs[x]
return score
def hanming(x, y):
"""计算两个字节流的汉明距离"""
num = 0
# 取较短长度进行比较
min_len = min(len(x), len(y))
for i in range(min_len):
# 计算异或结果中1的个数
t = x[i] ^ y[i]
while t:
if t & 1:
num += 1
t >>= 1
return num
def thechar(st1):
"""找到最佳的单字节解密密钥"""
max_score = 0
best_key = ''
for i in range(0, 256):
tmp = []
for j in range(len(st1)):
# 异或操作解密
tmp.append(chr(i ^ int(st1[j], 16)))
tmpstr = "".join(tmp)
# 计算英文文本评分
score = english_test(tmpstr)
if score > max_score:
max_score = score
best_key = chr(i)
return best_key
# 分析可能的密钥长度(1到40)
ans = []
for key_len in range(1, 41):
# 将密文分成4个块
blocks = []
for i in range(4):
start = i * key_len
end = start + key_len
blocks.append(wenben[start:end])
# 计算所有块之间的平均汉明距离
distances = []
for i in range(4):
for j in range(i+1, 4):
distances.append(hanming(blocks[i], blocks[j]) / key_len)
avg_distance = sum(distances) / len(distances)
ans.append((key_len, avg_distance))
# 按汉明距离排序(Python 3使用key参数替代cmp)
ans.sort(key=lambda x: x[1])
# 打印可能的密钥长度及其平均汉明距离
for item in ans:
print(f"密钥长度: {item[0]}, 平均汉明距离: {item[1]}")
# 确定密钥长度为29(根据分析结果)
key_length = 29
print(f"\n选择的密钥长度: {key_length}")
# 将密文转换为十六进制字符串
hex_wenben = binascii.hexlify(wenben).decode('utf-8')
# 按密钥长度分块(每个块包含29个字节,对应58个十六进制字符)
block_size = key_length * 2 # 每个字节对应2个十六进制字符
blocks = re.findall(rf'.{{{block_size}}}', hex_wenben)
# 分割每个块为字节
blocks = [re.findall(r'(.{2})', block) for block in blocks]
# 确定密钥的每个字符
keyy = []
for i in range(key_length):
# 收集每个块的第i个字节
column = [block[i] for block in blocks if i < len(block)]
# 找到最佳解密字符
key_char = thechar(column)
keyy.append(key_char)
keyy = "".join(keyy)
print("\n找到的密钥:")
print(keyy)
# 解密密文
an = []
key_bytes = keyy.encode('utf-8')
for i in range(len(wenben)):
# 循环使用密钥
decrypted_byte = wenben[i] ^ key_bytes[i % key_length]
an.append(chr(decrypted_byte))
# 输出解密结果
print("\n解密结果:")
print("".join(an))
keyboard
python
# _*_ coding:utf-8 _*_
"""
@author km
@time: 2019/10/18 11:34
"""
# 暴力破解SHA1哈希值
import re
import hashlib
import itertools
import datetime
starttime = datetime.datetime.now()
hash1 = "67ae1a64661ac8b4494666f58c4822408dd0a3e4" # 目标哈希值
# 字符选择集:每个位置有2种可选字符
str2 = [
['Q', 'q'], # 位置0的可选字符
['W', 'w'], # 位置1的可选字符
['%', '5'], # 位置2的可选字符
['8', '('], # 位置3的可选字符
['=', '0'], # 位置4的可选字符
['I', 'i'], # 位置5的可选字符
['*', '+'], # 位置6的可选字符
['n', 'N'] # 位置7的可选字符
]
def sha_encrypt(s):
"""计算字符串的SHA1哈希值"""
sha = hashlib.sha1(s.encode('utf-8')) # Python 3需要先编码为字节流
return sha.hexdigest()
# 初始化8位字符列表
str3 = ['0'] * 8
# 8层循环:为每个位置选择字符(每个位置2种选择)
for a in range(0, 2):
str3[0] = str2[0][a]
for b in range(0, 2):
str3[1] = str2[1][b]
for c in range(0, 2):
str3[2] = str2[2][c]
for d in range(0, 2):
str3[3] = str2[3][d]
for e in range(0, 2):
str3[4] = str2[4][e]
for f in range(0, 2):
str3[5] = str2[5][f]
for g in range(0, 2):
str3[6] = str2[6][g]
for h in range(0, 2):
str3[7] = str2[7][h]
newS = "".join(str3)
# 生成所有可能的排列组合
for i in itertools.permutations(newS, 8):
candidate = "".join(i)
hash_result = sha_encrypt(candidate)
if hash_result == hash1:
print(candidate) # 找到匹配的明文
endtime = datetime.datetime.now()
print((endtime - starttime).seconds) # 输出耗时
exit(0)