MoeCTF 2023 feistel

刚好昨天学习了feistel结构的加解密
题目给出的加密源码:

from Crypto.Util.number import *

round = 2
flag = open("./secret", "rb").read().strip()


def f(m, key):
    m = m ^ (m >> 4)
    m = m ^ (m << 5)
    m = m ^ (m >> 8)
    m ^= key
    m = (m * 1145 + 14) % 2**64
    m = (m * 1919 + 810) % 2**64
    m = (m * key) % 2**64
    return m


def enc(m, key, round):
    key = bytes_to_long(key)
    left = bytes_to_long(m[:8])
    right = bytes_to_long(m[8:])
    for i in range(round):
        left, right = right, f(right, key) ^ left
    left, right = right, left
    return long_to_bytes(left).rjust(8, b"\x00") + long_to_bytes(right).rjust(8, b"\x00")


def padding(m):
    mlen = len(m)
    pad = 16 - mlen % 16
    return m + pad * bytes([pad])


def ecb_enc(m, key):
    m = padding(m)
    mlen = len(m)
    c = b""
    for i in range(mlen // 16):
        c += enc(m[i * 16 : i * 16 + 16], key, round)
    return c


print(ecb_enc(flag, b"wulidego"))

# b'\x0b\xa7\xc6J\xf6\x80T\xc6\xfbq\xaa\xd8\xcc\x95\xad[\x1e\'W5\xce\x92Y\xd3\xa0\x1fL\xe8\xe1"^\xad'

正式经典的feistel加密结构:左右两部分分别变换后交换组合
image
而且这道题关键加密只有一条语句

left, right = right, f(right, key) ^ left

所以直接用密文套一次加密函数即可反向得到明文:

cipher =  b'\x0b\xa7\xc6J\xf6\x80T\xc6\xfbq\xaa\xd8\xcc\x95\xad[\x1e\'W5\xce\x92Y\xd3\xa0\x1fL\xe8\xe1"^\xad'
print(ecb_enc(cipher,b"wulidego"))

image

posted @ 2023-10-02 09:50  N0zoM1z0  阅读(84)  评论(0编辑  收藏  举报