网站Logo Cat&Dog

第二届熵密杯复现

betacat
18
2025-07-15

初始谜题

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))
动物装饰