第二次课
1_课前:流密码BBF实验-Build
#第1关:利用LFSR生成随机比特序列
class LFSR:
def __init__(self, seed):
# 确保种子是一个bytes
seed = int.from_bytes(seed, byteorder='big')
self.state = seed
self.tap_positions = [0, 10, 30, 31] # 示例反馈位位置
self.length = 32 # 固定32位长度
def next_bit(self):
# 计算反馈位
feedback_bit = 0
for tap in self.tap_positions:
feedback_bit ^= (self.state >> (self.length - tap - 1)) & 1
# 更新状态
self.state = ((self.state << 1) | feedback_bit) & 0xffffffff
return feedback_bit
def generate_bits_list(self, n):
return [self.next_bit() for _ in range(n)]
def generate_bits_str(self, n):
bits = self.generate_bits_list(n)
return ''.join(str(bit) for bit in bits)
def generate_bytes(self, n):
bits = self.generate_bits_str(n * 8)
bits_int = int(bits, 2)
bits_bytes = bits_int.to_bytes(n, 'big')
return bits_bytes
if __name__ == '__main__':
#读取种子(16进制编码)
seed = bytes.fromhex(input())
#以种子作为lfsr设置初始状态
lfsr = LFSR(seed)
# 生成16个随机字节
random_bytes = lfsr.generate_bytes(16)
# 以16进制形式打印
print(random_bytes.hex())
#第2关:利用LFSR实现流密码加密
def xor(bs1, bs2):
return bytes(a ^ b for a, b in zip(bs1, bs2))
class LFSR:
def __init__(self, seed):
# 确保种子是一个bytes
seed = int.from_bytes(seed, byteorder='big')
self.state = seed
self.tap_positions = [0, 10, 30, 31] # 示例反馈位位置
self.length = 32 # 固定32位长度
def next_bit(self):
# 计算反馈位
feedback_bit = 0
for tap in self.tap_positions:
feedback_bit ^= (self.state >> (self.length - tap - 1)) & 1
# 更新状态
self.state = ((self.state << 1) | feedback_bit) & 0xffffffff
return feedback_bit
def generate_bits_list(self, n):
return [self.next_bit() for _ in range(n)]
def generate_bits_str(self, n):
bits = self.generate_bits_list(n)
return ''.join(str(bit) for bit in bits)
def generate_bytes(self, n):
bits = self.generate_bits_str(n * 8)
bits_int = int(bits, 2)
bits_bytes = bits_int.to_bytes(n, 'big')
return bits_bytes
def encrypt(self, message):
'''
对message进行流密码加密
:param message: 明文,类型为bytes
:return: 密文,类型为bytes
'''
# 在此处填写代码
keystream = self.generate_bytes(len(message))
cipher=xor(keystream,message)
return cipher
if __name__ == '__main__':
#读取明文
message = input().encode('utf8')
#读取密钥
key = bytes.fromhex(input())
#将密钥设置为LFSR种子
lfsr = LFSR(key)
#调用LFSR的encrypt函数对明文加密
cipher = lfsr.encrypt(message)
#用16进制将密文字节输出
print(cipher.hex())
#第3关:利用LFSR实现流密码解密
def xor(bs1, bs2):
return bytes(a ^ b for a, b in zip(bs1, bs2))
class LFSR:
def __init__(self, seed):
# 确保种子是一个bytes
seed = int.from_bytes(seed, byteorder='big')
self.state = seed
self.tap_positions = [0, 10, 30, 31] # 示例反馈位位置
self.length = 32 # 固定32位长度
def next_bit(self):
# 计算反馈位
feedback_bit = 0
for tap in self.tap_positions:
feedback_bit ^= (self.state >> (self.length - tap - 1)) & 1
# 更新状态
self.state = ((self.state << 1) | feedback_bit) & 0xffffffff
return feedback_bit
def generate_bits_list(self, n):
return [self.next_bit() for _ in range(n)]
def generate_bits_str(self, n):
bits = self.generate_bits_list(n)
return ''.join(str(bit) for bit in bits)
def generate_bytes(self, n):
bits = self.generate_bits_str(n * 8)
bits_int = int(bits, 2)
bits_bytes = bits_int.to_bytes(n, 'big')
return bits_bytes
def encrypt(self, message):
'''
对message进行流密码加密
:param message: 明文,类型为bytes
:return: 密文,类型为bytes
'''
length_message = len(message)
key_stream = lfsr.generate_bytes(length_message)
cipher = xor(message, key_stream)
return cipher
if __name__ == '__main__':
#读取密文
cipher = bytes.fromhex(input())
#读取密钥
key = bytes.fromhex(input())
#对密文解密
#在此处填写代码
lfsr = LFSR(key)
plain = lfsr.encrypt(cipher)
#utf8对明文字节序列解码后输出
print(plain.decode('utf8'))
2-课中 流密码加解密
#第1关:流密码加密
def RC4_generate_keystream(key, length):
#初始化RC4状态
key_length = len(key)
S = list(range(256)) # S盒
j = 0
for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
S[i], S[j] = S[j], S[i] # 交换S[i]和S[j]
#生成密钥流
i = j = 0
keystream = []
for _ in range(length):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i] # 交换S[i]和S[j]
K = S[(S[i] + S[j]) % 256]
keystream.append(K)
return keystream
def xor(bs1, bs2):
return bytes(a ^ b for a, b in zip(bs1, bs2))
# 在下方的Begin和End之间填写代码,删除#开头的注释,实现流密码加密,后输出结果
# =========================Begin==========================
def RC4_encrypt(key, plaintext):
'''
:param key:密钥,类型为bytes
:param plaintext: 明文,类型为bytes
:return: 加密后的密文,类型为bytes
'''
# 在此处填写代码
key_length = 256
keystream=RC4_generate_keystream(key, key_length)
cipher_bytes=xor(keystream,plaintext)
return cipher_bytes
# =========================End============================
key = bytes.fromhex(input(""))
plaintext = input("").encode('utf8')
cipher_bytes = RC4_encrypt(key, plaintext)
print(cipher_bytes.hex())
#第2关:流密码解密
def RC4_generate_keystream(key, length):
#始化RC4状态
key_length = len(key)
S = list(range(256)) # S盒
j = 0
for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
S[i], S[j] = S[j], S[i] # 交换S[i]和S[j]
#生成密钥流
i = j = 0
keystream = []
for _ in range(length):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i] # 交换S[i]和S[j]
K = S[(S[i] + S[j]) % 256]
keystream.append(K)
return keystream
def xor(bs1, bs2):
return bytes(a ^ b for a, b in zip(bs1, bs2))
# 在下方的Begin和End之间填写代码,删除#开头的注释,实现流密码解密,后输出结果
# =========================Begin==========================
def RC4_decrypt(key, ciphertext):
'''
:param key:密钥,类型为bytes
:param ciphertext: 密钥,类型为bytes
:return: 解密后的明文,类型为bytes
'''
# 在此处填写代码
keylength=256
keystream=RC4_generate_keystream(key, keylength)
plaintext=xor(keystream,ciphertext)
return plaintext
# =========================End============================
key = bytes.fromhex(input(""))
ciphertext = bytes.fromhex(input(""))
plaintext = RC4_decrypt(key, ciphertext)
print(plaintext.decode('utf8'))
3-课后 流密码与已知明文攻击
#第1关:已知明文攻击
def xor(bs1, bs2):
return bytes(a ^ b for a, b in zip(bs1, bs2))
#假设已知两条密文,这两个密文分别由两条明文消息使用的相同的密钥通过流密码加密得来,且已知第一条密文对应的明文消息,请想办法还原出第二条密文对应的明文消息
cipher1 = bytes.fromhex(input(""))
cipher2 = bytes.fromhex(input(""))
message1 = bytes.fromhex(input(""))
# 在下方的Begin和End之间填写代码,删除#开头的注释,实现破解密文,后输出结果
# =========================Begin==========================
def crack_message2(cipher1, cipher2, message1):
'''
:param cipher1:已知的第一条密文,类型为bytes
:param cipher2: 已知的第二条密文,类型为bytes
:param message1: 已知的第一条密文对应的明文,类型为bytes
:return: 第二条密文对应的明文,类型为bytes
'''
keystream=xor(cipher1,message1)
message2=xor(cipher2,keystream)
return message2
# =========================End============================
message2 = crack_message2(cipher1, cipher2, message1)
print(message2.hex())
第一次课
1-课前 字节序列异或计算
def xor(bs1, bs2):
# =========================Begin==========================
result = bytes(a ^ b for a, b in zip(bs1, bs2))
# =========================end==========================
return result
# 从键盘输入两个字节序列
bs1_hex = input("")
bs2_hex = input("")
# 将输入的字符串转换为字节序列
bs1 = bytes.fromhex(bs1_hex)
bs2 = bytes.fromhex(bs2_hex)
xor_result = xor(bs1, bs2)
print(xor_result.hex())
2-课中-暴力破解
def Caesar_decrypt(key, cipher):
message = ''
for t in cipher:
if ord(t) >= ord('A') and ord(t) <= ord('Z'):
t_int = ord(t) - ord('A')
m_int = (t_int - key) % 26
m = chr(m_int + ord('A'))
message += m
elif ord(t) >= ord('a') and ord(t) <= ord('z'):
t_int = ord(t) - ord('a')
m_int = (t_int - key) % 26
m = chr(m_int + ord('a'))
message += m
else:
message += t
return message
# 读入凯撒密码加密后的密文
import sys
encrypt_text = sys.stdin.read()
# 暴力破解密钥和明文
# 遍历密钥所有可能的值,并解密相应的明文
for key in range(26) :
print('\n*********************************************')
print('尝试密钥:', key)
plain_text = Caesar_decrypt(key, encrypt_text)
print(plain_text)
# 请分析上面暴力破解结果,删除横线,输入正确的密钥值并解密出正确的明文
print('最有可能的密钥为:', 13)
plain_text = Caesar_decrypt(13, encrypt_text)
print(plain_text)
3-课后-频率分析
#第1关:简单的频率分析
from CaesarDecrypt import Caesar_decrypt
# 读取加密文本
import sys
encrypted_text = sys.stdin.read()
# 创建一个字典来存储字母频率
frequency = {}
# 遍历文本中的每个字符
for char in encrypted_text.lower():
# 只统计英文字母
if char.isalpha():
if char in frequency:
frequency[char] += 1
else:
frequency[char] = 1
# 将字典转换为列表
frequency_list = [(char, freq) for char, freq in frequency.items()]
# 按照频率由高到低排序列表
frequency_list.sort(key=lambda x: x[1], reverse=True)
# 找到出现频率最高的字符
highest_frequency_char = max(frequency, key=frequency.get)
# 计算这个字符与字母'E'之间的差距,即为最有可能得密钥
best_key = ord( highest_frequency_char ) - ord('e')
# 利用密钥对密文解密并输出
plaintext = Caesar_decrypt(best_key, encrypted_text)
print(plaintext)
#第2关:基于重合指数的频率分析
# 正常英文字符频率分布(基于英文统计数据)
normal_frequency = {
'a': 8.167, 'b': 1.492, 'c': 2.782, 'd': 4.253, 'e': 12.702,
'f': 2.228, 'g': 2.015, 'h': 6.094, 'i': 6.966, 'j': 0.153,
'k': 0.772, 'l': 4.025, 'm': 2.406, 'n': 6.749, 'o': 7.507,
'p': 1.929, 'q': 0.095, 'r': 5.987, 's': 6.327, 't': 9.056,
'u': 2.758, 'v': 0.978, 'w': 2.360, 'x': 0.150, 'y': 1.974,
'z': 0.074
}
# 读取加密文本
import sys
encrypted_text = sys.stdin.read()
# 统计密文字符频率
encrypted_frequency = {}
for char in encrypted_text.lower():
if char.isalpha():
encrypted_frequency[char] = encrypted_frequency.get(char, 0) + 1
# 计算重合指数
def calculate_coincidence_index(frequency, normal_freq):
sum_of_square_of_fi = 0
sum_of_square_of_ni = 0
sum_of_cross_multiplication_of_fi_and_ni = 0
for char in 'abcdefghijklmnopqrstuvwxyz':
sum_of_square_of_fi += (frequency[char] * frequency[char])
sum_of_square_of_ni += (normal_freq[char] * normal_freq[char])
sum_of_cross_multiplication_of_fi_and_ni += frequency[char] * normal_freq[char]
return sum_of_cross_multiplication_of_fi_and_ni/(sum_of_square_of_fi*sum_of_square_of_ni)
return coincidences
# 计算每个可能的移位密钥的重合指数
for shift in range(26):
shifted_freq = {chr((ord(char) - 97 + shift) % 26 + 97): freq
for char, freq in encrypted_frequency.items()}
coincidence_index = calculate_coincidence_index(shifted_freq, normal_frequency)
# print('移位', shift, '的重合指数为',coincidence_index)
# 找到最高重合指数对应的移位
best_shift = max(range(26), key=lambda shift: calculate_coincidence_index(
{chr((ord(char) - 97 + shift) % 26 + 97): freq
for char, freq in encrypted_frequency.items()}, normal_frequency))
best_key = 26 - best_shift
#使用最有可能的密钥解密,将解密所得明文写入目标文件
from CaesarDecrypt import Caesar_decrypt
plain_cracked = Caesar_decrypt(best_key, encrypted_text)
print(plain_cracked)