初始谜题
1
请下载题目附件,并获取在线场景,双击运行附件中的客户端,输入IP地址和端口号连接服务端。请认真分析题目附件中的代码,根据服务端所给出的密文,解密出所对应的明文消息,并提交至服务端。
from sympy import Mod, Integer
from sympy.core.numbers import mod_inverse
# 模数
N_HEX = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"
MODULUS = Integer(int(N_HEX, 16))
MSG_PREFIX = "CryptoCup message:"
# 加密函数
def encrypt_message(message, key):
# 添加前缀
message_with_prefix = MSG_PREFIX + message
message_bytes = message_with_prefix.encode('utf-8')
message_len = len(message_bytes)
num_blocks = (message_len + 15) // 16
blocks = [message_bytes[i * 16:(i + 1) * 16] for i in range(num_blocks)]
# 进行0填充
blocks[-1] = blocks[-1].ljust(16, b'\x00')
encrypted_blocks = []
k = key
# 加密每个分组
for block in blocks:
block_int = int.from_bytes(block, byteorder='big')
encrypted_block_int = Mod(block_int * k, MODULUS)
encrypted_blocks.append(encrypted_block_int)
k += 1 # 密钥自增1
# 将加密后的分组连接成最终的密文
encrypted_message = b''.join(
int(block_int).to_bytes(32, byteorder='big') for block_int in encrypted_blocks
)
return encrypted_message
# 解密函数
def decrypt_message(encrypted_message, key):
num_blocks = len(encrypted_message) // 32
blocks = [encrypted_message[i * 32:(i + 1) * 32] for i in range(num_blocks)]
decrypted_blocks = []
k = key
# 解密每个分组
for block in blocks:
block_int = int.from_bytes(block, byteorder='big')
key_inv = mod_inverse(k, MODULUS)
decrypted_block_int = Mod(block_int * key_inv, MODULUS)
decrypted_blocks.append(decrypted_block_int)
k += 1 # 密钥自增1
# 将解密后的分组连接成最终的明文
decrypted_message = b''.join(
int(block_int).to_bytes(16, byteorder='big') for block_int in decrypted_blocks
)
# 去除前缀
if decrypted_message.startswith(MSG_PREFIX.encode('utf-8')):
decrypted_message = decrypted_message[len(MSG_PREFIX):]
return decrypted_message.rstrip(b'\x00').decode('utf-8')
# 测试
initial_key = Integer(0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0)
message = "Hello, this is a test message."
print("Original Message:", message)
# 加密
encrypted_message = encrypt_message(message, initial_key)
print("Encrypted Message (hex):", encrypted_message.hex())
# 解密
decrypted_message = decrypt_message(encrypted_message, initial_key)
print("Decrypted Message:", decrypted_message)
分组密码,由于添加了固定的18字节前缀,而分组长度又是16字节,可以通过第一组推出key,进而解密
encrypted\_block\_int \equiv block\_int \times k \pmod{MODULUS}
\Rightarrow k \equiv encrypted\_block\_int \times block\_int^{-1} \pmod {MODULUS}
\Rightarrow block\_int \equiv encrypted\_block\_int \times k^{-1} \pmod {MODULUS}
from Crypto.Util.number import *
cipher = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\xcb\xd6\x92\xa5|-+\xea\x8e \xfe\xce\xac\xec\x9f\xe7\xbaBH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x072\xcb\x1fC\x17\xf04[\xd6\x16QW\xa1,)\xd8\xf4h \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05%\xee\xae8\x99\xc8B\x06\xc5J$\x08\xef\xe4\xcd\x91\xba\x00\x00'
N_HEX = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"
MSG_PREFIX = "CryptoCup message:"
encrypted_block = [bytes_to_long(cipher[i * 32 : (i + 1) * 32]) for i in range ((len(cipher) + 31 ) // 32)]
key = encrypted_block[0] * inverse(bytes_to_long(MSG_PREFIX[:16].encode()), int(N_HEX, 16)) % int(N_HEX, 16)
msg = ''
for i in encrypted_block:
p = i * inverse(key, int(N_HEX, 16)) % int(N_HEX, 16)
key += 1
msg += (long_to_bytes(p).decode())
print(msg[18:])
2
请下载题目附件,并获取在线场景,双击运行附件中的客户端,输入IP地址和端口号连接服务端。请认真分析题目附件中的代码,根据服务端所给出的counter和token,伪造出一个可以通过验证的counter和token,并提交至服务端。
import binascii
from gmssl import sm3
# 读取HMAC key文件
def read_hmac_key(file_path):
with open(file_path, 'rb') as f:
hmac_key = f.read().strip()
return hmac_key
# 生成token
def generate_token(hmac_key, counter):
# 如果HMAC_KEY长度不足32字节,则在末尾补0,超过64字节则截断
if len(hmac_key) < 32:
hmac_key = hmac_key.ljust(32, b'\x00')
elif len(hmac_key) > 32:
hmac_key = hmac_key[:32]
# 将计数器转换为字节表示
counter_bytes = counter.to_bytes((counter.bit_length() + 7) // 8, 'big')
# print("counter_bytes:", binascii.hexlify(counter_bytes))
tobe_hashed = bytearray(hmac_key + counter_bytes)
# print("tobe_hashed:", binascii.hexlify(tobe_hashed))
# 使用SM3算法计算哈希值
sm3_hash = sm3.sm3_hash(tobe_hashed)
# 将SM3的哈希值转换为十六进制字符串作为token
token = sm3_hash
return token
current_counter = 0
def verify_token(hmac_key, counter, token):
# 生成token
generated_token = generate_token(hmac_key, counter)
global current_counter
# 比较生成的token和输入的token是否相同
if generated_token == token:
if counter & 0xFFFFFFFF > current_counter:
current_counter = counter & 0xFFFFFFFF
print("current_counter: ", hex(current_counter))
return "Success"
else:
return "Error: counter must be increasing"
else:
return "Error: token not match"
# 假设HMAC key文件路径
hmac_key_file = 'hmac_key.txt'
# 假设计数器值
counter = 0x12345678
# 读取HMAC key
hmac_key = read_hmac_key(hmac_key_file)
# 生成token
token = generate_token(hmac_key, counter)
print("Generated token:", token)
print(verify_token(hmac_key, counter, token))