密文是e35d1c09d861670051587475dba013bfe253923f8571add...
作成日: 2026年1月25日
使用モデル GPT-5.2 Thinking by Chat01
作成日: 2026年1月25日
使用モデル GPT-5.2 Thinking by Chat01
pythonfrom typing import List, Tuple # Implement SM4 SM4_SBOX = [ 0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05, 0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99, 0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62, 0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6, 0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8, 0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35, 0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87, 0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e, 0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1, 0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3, 0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f, 0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51, 0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8, 0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0, 0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84, 0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48 ] SM4_FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc] SM4_CK = [ 0x00070e15,0x1c232a31,0x383f464d,0x545b6269, 0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9, 0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249, 0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9, 0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229, 0x30373e45,0x4c535a61,0x686f767d,0x848b9299, 0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209, 0x10171e25,0x2c333a41,0x484f565d,0x646b7279 ] def rotl32(x, n): x &= 0xffffffff return ((x<<n)&0xffffffff) | (x>>(32-n)) def tau(a: int) -> int: # substitute each byte with S-box b0 = SM4_SBOX[(a>>24)&0xff] b1 = SM4_SBOX[(a>>16)&0xff] b2 = SM4_SBOX[(a>>8)&0xff] b3 = SM4_SBOX[a&0xff] return (b0<<24)|(b1<<16)|(b2<<8)|b3 def L(b: int) -> int: return b ^ rotl32(b,2) ^ rotl32(b,10) ^ rotl32(b,18) ^ rotl32(b,24) def Lp(b: int) -> int: return b ^ rotl32(b,13) ^ rotl32(b,23) def T(x: int) -> int: return L(tau(x)) def Tp(x: int) -> int: return Lp(tau(x)) def bytes_to_u32_be(b: bytes) -> int: return int.from_bytes(b, 'big') def u32_to_bytes_be(x: int) -> bytes: return (x & 0xffffffff).to_bytes(4,'big') def sm4_setkey(key: bytes) -> List[int]: MK = [bytes_to_u32_be(key[i*4:(i+1)*4]) for i in range(4)] K = [MK[i] ^ SM4_FK[i] for i in range(4)] rk = [] for i in range(32): t = K[i+1] ^ K[i+2] ^ K[i+3] ^ SM4_CK[i] K.append(K[i] ^ Tp(t)) rk.append(K[i+4] & 0xffffffff) return rk def sm4_crypt_block(inp: bytes, rk: List[int]) -> bytes: X = [bytes_to_u32_be(inp[i*4:(i+1)*4]) for i in range(4)] for i in range(32): t = X[i+1] ^ X[i+2] ^ X[i+3] ^ rk[i] X.append(X[i] ^ T(t)) # output is X[35..32] reversed out_words = X[35:31:-1] return b''.join(u32_to_bytes_be(w) for w in out_words) def sm4_ecb_decrypt(cipher: bytes, key: bytes) -> bytes: assert len(cipher) % 16 == 0 rk = sm4_setkey(key) rk_dec = list(reversed(rk)) pt = b''.join(sm4_crypt_block(cipher[i:i+16], rk_dec) for i in range(0,len(cipher),16)) return pt def pkcs7_unpad(data: bytes, block=16) -> bytes: if not data or len(data)%block!=0: raise ValueError("invalid length") pad = data[-1] if pad<1 or pad>block: raise ValueError("bad padding") if data[-pad:] != bytes([pad])*pad: raise ValueError("bad padding") return data[:-pad] cipher_hex="e35d1c09d861670051587475dba013bfe253923f8571add70f63a674dbeb8f22" cipher=bytes.fromhex(cipher_hex) key=bytes([0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]) pt_padded=sm4_ecb_decrypt(cipher,key) pt_padded, pt_padded.hex(), len(pt_padded) (b'yqv\x03\x9dTm&\x17\xfdJ\x8f\x91\'c"\x90\x1e\\\xbb\x16\xf5\xf7{}\x87\xb9Y\xe7\xe67\xaf', '797176039d546d2617fd4a8f91276322901e5cbb16f5f77b7d87b959e7e637af', 32)
pythondef sm4_ecb_encrypt(plain: bytes, key: bytes) -> bytes: assert len(plain)%16==0 rk=sm4_setkey(key) return b''.join(sm4_crypt_block(plain[i:i+16], rk) for i in range(0,len(plain),16)) key=bytes.fromhex("0123456789abcdeffedcba9876543210") pt=bytes.fromhex("0123456789abcdeffedcba9876543210") ct=sm4_ecb_encrypt(pt,key) ct.hex() '681edf34d206965e86b3e94f536e4246'
pythonct2=sm4_ecb_encrypt(pt_padded,key) # encrypt padded bytes with key ct2.hex(), cipher_hex==ct2.hex() ('e35d1c09d861670051587475dba013bfe253923f8571add70f63a674dbeb8f22', True)
pythonpt=pt_padded # Try interpret as ascii/utf8 for enc in ['utf-8','latin1','gbk']: try: print(enc, pt.decode(enc)) except Exception as e: print(enc, "decode error", e) # show printable proportion import string print("printable count", sum(chr(b) in string.printable for b in pt), "len", len(pt))
从你给的 c_sm4.exe 里(反汇编 main)可以直接看到 SM4 的密钥被写死为:
01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10
按标准 SM4-ECB 对你这段 32 字节密文做解密,得到明文(原始字节)为:
797176039d546d2617fd4a8f91276322901e5cbb16f5f77b7d87b959e7e637afb"yqv\x03\x9dTm&\x17\xfdJ\x8f\x91'c\"\x90\x1e\\\xbb\x16\xf5\xf7{}\x87\xb9Y\xe7\xe67\xaf"下面给你一份可直接跑的 Python 脚本(纯实现 SM4):
python# -*- coding: utf-8 -*- # SM4-ECB decrypt (pure python) SBOX = [ 0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05, 0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99, 0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62, 0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6, 0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8, 0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35, 0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87, 0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e, 0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1, 0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3, 0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f, 0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51, 0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8, 0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0, 0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84, 0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48 ] FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc] CK = [ 0x00070e15,0x1c232a31,0x383f464d,0x545b6269,0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9, 0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9, 0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,0x30373e45,0x4c535a61,0x686f767d,0x848b9299, 0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,0x10171e25,0x2c333a41,0x484f565d,0x646b7279 ] def rotl32(x, n): x &= 0xffffffff return ((x << n) & 0xffffffff) | (x >> (32 - n)) def tau(a): return ((SBOX[(a >> 24) & 0xff] << 24) | (SBOX[(a >> 16) & 0xff] << 16) | (SBOX[(a >> 8) & 0xff] << 8) | SBOX[a & 0xff]) def L(b): return b ^ rotl32(b,2) ^ rotl32(b,10) ^ rotl32(b,18) ^ rotl32(b,24) def Lp(b): return b ^ rotl32(b,13) ^ rotl32(b,23) def T(x): return L(tau(x)) def Tp(x): return Lp(tau(x)) def u32(b): return int.from_bytes(b, "big") def b4(x): return (x & 0xffffffff).to_bytes(4, "big") def setkey(key16: bytes): MK = [u32(key16[i*4:(i+1)*4]) for i in range(4)] K = [MK[i] ^ FK[i] for i in range(4)] rk = [] for i in range(32): K.append(K[i] ^ Tp(K[i+1] ^ K[i+2] ^ K[i+3] ^ CK[i])) rk.append(K[i+4] & 0xffffffff) return rk def crypt_block(block16: bytes, rk): X = [u32(block16[i*4:(i+1)*4]) for i in range(4)] for i in range(32): X.append(X[i] ^ T(X[i+1] ^ X[i+2] ^ X[i+3] ^ rk[i])) return b"".join(b4(w) for w in X[35:31:-1]) def sm4_ecb_decrypt(cipher: bytes, key16: bytes) -> bytes: assert len(cipher) % 16 == 0 rk = setkey(key16) rk = list(reversed(rk)) # decrypt = reverse roundkeys out = b"" for i in range(0, len(cipher), 16): out += crypt_block(cipher[i:i+16], rk) return out if __name__ == "__main__": ct_hex = "e35d1c09d861670051587475dba013bfe253923f8571add70f63a674dbeb8f22" key_hex = "0123456789abcdeffedcba9876543210" ct = bytes.fromhex(ct_hex) key = bytes.fromhex(key_hex) pt = sm4_ecb_decrypt(ct, key) print("PT(hex):", pt.hex()) print("PT(raw):", pt) # 需要的话可以尝试按不同编码解码 for enc in ("utf-8", "gbk", "latin1"): try: print(f"PT({enc}):", pt.decode(enc)) except Exception: pass
如果你原本“期望输出是可读字符串/flag”,那这个密文很可能不是这个程序里“字符串+PKCS7填充”的产物(因为解出来末尾不是合法 PKCS7 padding)。你可以把我给的明文 hex 再发我,我帮你继续看下一步(比如再做一次解密/异或/编码处理)。
输入之后
Enter a string to encrypt and decrypt: 797176039d546d2617fd4a8f91276322901e5cbb16f5f77b7d87b959e7e637af
Encrypted (Hex): 534f10044e5687e0bef09a06ad343ad43526b3ad080e34eda3e0f3468c4aec2bdaa83585102f8d030029532e9835f32ac56392a1d2dc9182dbc6f678dc5bec3cd5d2bbf39261ef433235a483db97b8da
密文最后不是e35d1c09d861670051587475dba013bfe253923f8571add70f63a674dbeb8f22
我需要密文是e35d1c09d861670051587475dba013bfe253923f8571add70f63a674dbeb8f22
输入之后
Enter a string to encrypt and decrypt: 797176039d546d2617fd4a8f91276322901e5cbb16f5f77b7d87b959e7e637af
Encrypted (Hex): 534f10044e5687e0bef09a06ad343ad43526b3ad080e34eda3e0f3468c4aec2bdaa83585102f8d030029532e9835f32ac56392a1d2dc9182dbc6f678dc5bec3cd5d2bbf39261ef433235a483db97b8da
密文最后不是e35d1c09d861670051587475dba013bfe253923f8571add70f63a674dbeb8f22
我需要密文是e35d1c09d861670051587475dba013bfe253923f8571add70f63a674dbeb8f22