一、哪些是“真加密”,哪些不是
1、真正的密码算法
对称分组密码:AES、DES、TEA/XTEA/XXTEA、SM4等
流密码:RC4等
非对称密码:RSA
哈希 / MAC / KDF:MD5、SHA-1、SHA-2、SHA-3
2、哪些是“真加密”,哪些不是
编码:Base16/32/58/62/64/85、URL Encode、UUEncode
简单位运算混淆:XOR、ADD/SUB、ROL/ROR、字节交换、位重排、查表替换
压缩:zlib、gzip
约束 / 验证:迷宫、矩阵、线性方程组、Z3
虚拟机壳 / 自定义字节码:VM、解释器、调度器
3、迷宫、Z3 的定位
迷宫:本质是路径约束 / 状态转移 / 图搜索
Z3:本质是 SMT 求解器,不是加密算法,而是拿来解“验证关系”
Z3 官方文档把它定义为定理证明器 / SMT 求解器,用来判断逻辑公式在某些理论下是否可满足。逆向里它最常见的用途是:把校验逻辑翻成 bit-vector 约束后直接求解
二、逆向识别总方法:先看这 10 件事
2.1 看输入输出长度关系
这是最快的第一判断:
- 长度变成 2 倍:像 hex / Base16
- 3 字节变 4 字符:像 Base64
- 4 字节变 5 字符:像 Base85
- 输出长度与输入相同:像 XOR、流密码、分组密码某些模式
- 固定输出 16/20/32/64 字节:像 MD5 / SHA1 / SHA256 / SHA512
2.2 看字符集
0-9A-Fa-f:hexA-Z2-7=:Base32A-Za-z0-9+/=:Base64A-Za-z0-9-_=:URL-safe Base64
2.3 看“块大小”
- 8 字节块:DES /TEA 家族常见
- 16 字节块:AES / SM4 常见
- 不分块、逐字节/逐字输出:流密码或编码
2.4 看循环轮数
很多算法有非常鲜明的轮数味道:
- AES:10 / 12 / 14 轮
- DES:16 轮
- TEA:常见 32 cycles(很多实现写成 32 次循环)
- SM4:32 轮
- SHA-1:80 步
- SHA-256:64 步
- MD5:64 步
2.5 看常量
常量是逆向识别最值钱的东西。
[Base]
Base64 table: A-Z a-z 0-9 + /
Base64 URL-safe: A-Z a-z 0-9 - _
Base32: A-Z 2-7
Base58: 无 0 O I l
[TEA]
delta = 0x9E3779B9
sum(dec start) = 0xC6EF3720
常见操作: <<4, >>5, +, ^
[XTEA]
k[sum & 3]
k[(sum >> 11) & 3]
[RC4]
S[256]
for i in 0..255 S[i]=i
KSA/PRGA + swap
[AES]
S-box 开头: 63 7C 77 7B F2 6B 6F C5
Rcon: 01 02 04 08 10 20 40 80 1B 36
AES-NI: aesenc/aesdec/aeskeygenassist
[DES]
8-byte block
16 rounds
大量置换表 + 8 个 S-box
[ChaCha20]
61707865 3320646e 79622d32 6b206574
rotation: 16,12,8,7
[Salsa20]
类似 16-word ARX
rotation: 7,9,13,18
[MD5]
IV:
67452301 EFCDAB89 98BADCFE 10325476
[SHA1]
IV:
67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0
K:
5A827999 6ED9EBA1 8F1BBCDC CA62C1D6
[SHA256]
IV:
6A09E667 BB67AE85 3C6EF372 A54FF53A
510E527F 9B05688C 1F83D9AB 5BE0CD19
[SM3]
IV:
7380166F 4914B2B9 172442D7 DA8A0600
A96F30BC 163138AA E38DEE4D B0FB0E4E
Tj:
79CC4519 / 7A879D8A
[HMAC]
ipad = 0x36
opad = 0x5C
[RSA]
e = 65537
2.6 看数据结构尺寸
一些算法的内部状态很有辨识度:
- RC4:
S[256] - AES:16-byte state,或 256 项 S-box / 4 张 T-table
- SHA-256:8 个 32-bit state + 64 个 round constant
- SHA-3/Keccak:5×5 lane 状态
- RSA/ECC:大量大整数 limb 运算
2.7 看操作形状
- 大量
xor + rol/ror + add:ARX 家族,常见于 TEA / XTEA - 大量查表:AES S-box、DES S-box、RC4 S 数组、Base 表
- 大量位置换 / 掩码:DES、bitslice AES、CRC、哈希
- 大整数乘模 / 平方模:RSA
2.8 看模式和 padding
很多题不是“算法本体”,而是“算法 + 模式 + padding”:
- ECB:重复块明文会出现重复密文块
- CBC:每块先 xor 前一密文块 / IV
- CTR:无 padding,计数器递增
- GCM:CTR + GHASH
- PKCS#7:尾部
01/02/03... - Zero padding:末尾全 0
2.9 看硬件指令 / API
- x86
aesenc/aesdec/aeskeygenassist:AES-NI - x86
pclmulqdq:GHASH / GCM 很常见 - x86 SHA 扩展:SHA-1 / SHA-256
- ARM
AESE/AESMC/AESD/AESIMC:ARM Crypto Extension - CUDA / OpenCL / HIP:GPU 并行核
Intel 官方文档说明 AES-NI 包含 6 条核心指令;Intel SHA Extensions 为 SHA-1 和 SHA-256 提供 7 条 SSE 指令;ARM A64 加密指令运行在 128-bit Advanced SIMD 寄存器上;CUDA/PTX/OpenCL/ROCm 官方文档都把 GPU/异构设备暴露成数据并行模型。
三、所有常见加解密方法代码详解
base64(任意形式改变解密)
import base64
# 自定义Base64字符表
custom_table='6789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345'
#原编码
std_table ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
# 密文
encoded_str = '1231231231'
# 字符映射和填充
translation = str.maketrans(custom_table, std_table)
translated_str = encoded_str.translate(translation)
pad_len = (-len(translated_str)) % 4
padded_str = translated_str + '=' * pad_len
try:
data = base64.b64decode(padded_str)
print("解码后的十六进制:", data.hex())
# 尝试UTF-8解码
flag = data.decode('utf-8')
print("UTF-8解码成功:", flag)
except Exception as e:
print("解码失败:", e)
TEA家族加解密
TEA
DELTA = 0x9E3779B9
MASK = 0xFFFFFFFF
def tea_encrypt(v, k):
v0, v1 = v
sum_ = 0
for _ in range(32):
sum_ = (sum_ + DELTA) & MASK
v0 = (v0 + (((v1 << 4) + k[0]) ^ (v1 + sum_) ^ ((v1 >> 5) + k[1]))) & MASK
v1 = (v1 + (((v0 << 4) + k[2]) ^ (v0 + sum_) ^ ((v0 >> 5) + k[3]))) & MASK
return v0, v1
def tea_decrypt(v, k):
v0, v1 = v
sum_ = (DELTA * 32) & MASK
for _ in range(32):
v1 = (v1 - (((v0 << 4) + k[2]) ^ (v0 + sum_) ^ ((v0 >> 5) + k[3]))) & MASK
v0 = (v0 - (((v1 << 4) + k[0]) ^ (v1 + sum_) ^ ((v1 >> 5) + k[1]))) & MASK
sum_ = (sum_ - DELTA) & MASK
return v0, v1
if __name__ == "__main__":
# 一组数据块:2 个 32 位整数
v = (0x12345678, 0x9ABCDEF0)
# 128-bit key:4 个 32 位整数
k = (0x11111111, 0x22222222, 0x33333333, 0x44444444)
enc = tea_encrypt(v, k)
dec = tea_decrypt(enc, k)
print("原文: ", [hex(x) for x in v])
print("加密: ", [hex(x) for x in enc])
print("解密: ", [hex(x) for x in dec])
XTEA
MASK = 0xffffffff
u32 = lambda x: x & MASK
def encipher(num_rounds, v, key):
v0, v1 = u32(v[0]), u32(v[1])
delta = 0x9E3779B9
sum_ = u32(0)
for _ in range(num_rounds):
t1 = u32(((v1 << 4) ^ (v1 >> 5)) + v1)
k1 = u32(sum_ + key[sum_ & 3])
v0 = u32(v0 + (t1 ^ k1))
sum_ = u32(sum_ + delta)
t2 = u32(((v0 << 4) ^ (v0 >> 5)) + v0)
k2 = u32(sum_ + key[(sum_ >> 11) & 3])
v1 = u32(v1 + (t2 ^ k2))
v[0], v[1] = v0, v1
def decipher(num_rounds, v, key):
v0, v1 = u32(v[0]), u32(v[1])
delta = 0x9E3779B9
sum_ = u32(delta * num_rounds)
for _ in range(num_rounds):
t2 = u32(((v0 << 4) ^ (v0 >> 5)) + v0)
k2 = u32(sum_ + key[(sum_ >> 11) & 3])
v1 = u32(v1 - (t2 ^ k2))
sum_ = u32(sum_ - delta)
t1 = u32(((v1 << 4) ^ (v1 >> 5)) + v1)
k1 = u32(sum_ + key[sum_ & 3])
v0 = u32(v0 - (t1 ^ k1))
v[0], v[1] = v0, v1
if __name__ == "__main__":
v = [1, 2]
k = [2, 2, 3, 4]
r = 32
print("加密前原始数据:{} {}".format(v[0], v[1]))
encipher(r, v, k)
print("加密后的数据:{} {}".format(v[0], v[1]))
decipher(r, v, k)
print("解密后的数据:{} {}".format(v[0], v[1]))
XXTEA
def shift(z, y, x, k, p, e):
return ((((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((x ^ y) + (k[(p & 3) ^ e] ^ z)))
def encrypt(v, k):
delta = 0x9E3779B9
n = len(v)
rounds = 6 + 52 / n
x = 0
z = v[n - 1]
for i in range(rounds):
x = (x + delta) & 0xFFFFFFFF
e = (x >> 2) & 3
for p in range(n - 1):
y = v[p + 1]
v[p] = (v[p] + shift(z, y, x, k, p, e)) & 0xFFFFFFFF
z = v[p]
p += 1
y = v[0]
v[n - 1] = (v[n - 1] + shift(z, y, x, k, p, e)) & 0xFFFFFFFF
z = v[n - 1]
return v
def decrypt(v, k):
delta = 0x9E3779B9
n = len(v)
rounds = 6 + 52 / n
x = (rounds * delta) & 0xFFFFFFFF
y = v[0]
for i in range(rounds):
e = (x >> 2) & 3
for p in range(n - 1, 0, -1):
z = v[p - 1]
v[p] = (v[p] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[p]
p -= 1
z = v[n - 1]
v[0] = (v[0] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[0]
x = (x - delta) & 0xFFFFFFFF
return v
if __name__ == '__main__':
plain = [1, 2]
key = [2, 2, 3, 4]
encrypted = encrypt(plain, key)
print(encrypted)
decrypted = decrypt(encrypted, key)
print(decrypted)
SM4
# 最简单 SM4 ECB 板子
# 适合 CTF 里直接解一块/多块数据
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,
]
MASK = 0xFFFFFFFF
def rol32(x, n):
"""32 位循环左移"""
x &= MASK
return ((x << n) & MASK) | (x >> (32 - n))
def tau(x):
"""非线性变换:4 个字节分别过 SBOX"""
return (
(SBOX[(x >> 24) & 0xFF] << 24) |
(SBOX[(x >> 16) & 0xFF] << 16) |
(SBOX[(x >> 8) & 0xFF] << 8) |
SBOX[x & 0xFF]
)
def L(x):
"""加解密轮函数里的线性变换"""
return x ^ rol32(x, 2) ^ rol32(x, 10) ^ rol32(x, 18) ^ rol32(x, 24)
def L_key(x):
"""密钥扩展里的线性变换"""
return x ^ rol32(x, 13) ^ rol32(x, 23)
def T(x):
"""轮函数 T = L(tau(x))"""
return L(tau(x))
def T_key(x):
"""密钥扩展 T' = L'(tau(x))"""
return L_key(tau(x))
def bytes_to_words(b):
"""16 字节 -> 4 个大端 32 位整数"""
return [int.from_bytes(b[i:i+4], "big") for i in range(0, 16, 4)]
def words_to_bytes(words):
"""4 个 32 位整数 -> 16 字节"""
return b"".join((x & MASK).to_bytes(4, "big") for x in words)
def expand_key(key16):
"""生成 32 个轮密钥"""
if len(key16) != 16:
raise ValueError("key 长度必须是 16 字节")
mk = bytes_to_words(key16)
K = [0] * 36
for i in range(4):
K[i] = mk[i] ^ FK[i]
rk = []
for i in range(32):
K[i + 4] = K[i] ^ T_key(K[i + 1] ^ K[i + 2] ^ K[i + 3] ^ CK[i])
rk.append(K[i + 4] & MASK)
return rk
def sm4_block(block16, rk, decrypt=False):
"""SM4 单块处理:输入必须是 16 字节"""
if len(block16) != 16:
raise ValueError("单块长度必须是 16 字节")
X = bytes_to_words(block16) + [0] * 32
# 解密就是轮密钥倒序
round_keys = rk[::-1] if decrypt else rk
for i in range(32):
X[i + 4] = X[i] ^ T(X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ round_keys[i])
return words_to_bytes([X[35], X[34], X[33], X[32]])
def sm4_ecb(data, key16, decrypt=False):
"""
SM4 ECB 模式
注意:这里不自动补齐,长度必须是 16 的倍数
"""
if len(data) % 16 != 0:
raise ValueError("ECB 数据长度必须是 16 的倍数")
rk = expand_key(key16)
out = b""
for i in range(0, len(data), 16):
out += sm4_block(data[i:i+16], rk, decrypt=decrypt)
return out
if __name__ == "__main__":
key = bytes.fromhex("ac46fb610b313b4f32fc642d8834b456")
ct = bytes.fromhex("49b351855f211b85bd012f80ce8ed5b3") # 当前只有 1 块 = 16 字节
# 解密
pt = sm4_ecb(ct, key, decrypt=True)
print("PT =", pt.hex())
print("PT(raw) =", pt)
# 回加密校验
ct_check = sm4_ecb(pt, key, decrypt=False)
print("RE-ENC MATCH:", ct_check == ct)
RC4
class RC4:
def __init__(self, key: bytes):
"""
初始化 RC4 类
:param key: 密钥,字节类型
"""
self.key = key
self.s = list(range(256)) # 初始化 S 数组
self._ksa() # 执行密钥调度算法
def _ksa(self):
"""
密钥调度算法 (Key Scheduling Algorithm, KSA)
"""
j = 0
key_length = len(self.key)
for i in range(256):
j = (j + self.s[i] + self.key[i % key_length]) % 256
self.s[i], self.s[j] = self.s[j], self.s[i] # 交换 S[i] 和 S[j]
def _prga(self):
"""
伪随机数生成算法 (Pseudo-Random Generation Algorithm, PRGA)
:yield: 生成的伪随机字节
"""
i = j = 0
while True:
i = (i + 1) % 256
j = (j + self.s[i]) % 256
self.s[i], self.s[j] = self.s[j], self.s[i] # 交换 S[i] 和 S[j]
yield self.s[(self.s[i] + self.s[j]) % 256]
def encrypt(self, plaintext: bytes) -> bytes:
"""
加密明文
:param plaintext: 明文,字节类型
:return: 密文,字节类型
"""
keystream = self._prga()
return bytes([p ^ next(keystream) for p in plaintext])
def decrypt(self, ciphertext: bytes) -> bytes:
"""
解密密文
:param ciphertext: 密文,字节类型
:return: 明文,字节类型
"""
# RC4 的加密和解密过程相同
return self.encrypt(ciphertext)
key = b"s3c4etKey"
plaintext = b"flag{9ec326a6c0ba06d824c52f2ad8602659}"
# 初始化 RC4 类
rc4 = RC4(key)
# 加密
ciphertext = rc4.encrypt(plaintext)
print("Ciphertext:", ciphertext)
# 解密
decrypted = rc4.decrypt(ciphertext)
print("Decrypted:", decrypted)
AES_128(AES只写简单的128了,其他的可以在此基础上自己加入)
SBOX = [
0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,
0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,
0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,
0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,
0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,
0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,
0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,
0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,
0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,
0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,
0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,
0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,
0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,
0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,
0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,
0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16
]
RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36]
def pkcs7_pad(data: bytes, block_size: int = 16) -> bytes:
"""PKCS#7 补位"""
pad_len = block_size - (len(data) % block_size)
return data + bytes([pad_len] * pad_len)
def xor_bytes(a, b):
return [x ^ y for x, y in zip(a, b)]
def xtime(x: int) -> int:
"""GF(2^8) 上乘 2"""
return (((x << 1) ^ 0x1B) & 0xFF) if (x & 0x80) else ((x << 1) & 0xFF)
def sub_bytes(state):
"""字节替换"""
return [SBOX[b] for b in state]
def shift_rows(state):
"""
行移位
这里 state 按 AES 标准使用列优先布局:
state[r + 4*c]
"""
out = state[:]
for r in range(4):
row = [state[r + 4 * c] for c in range(4)]
row = row[r:] + row[:r] # 左移 r 位
for c in range(4):
out[r + 4 * c] = row[c]
return out
def mix_columns(state):
"""列混合"""
out = state[:]
for c in range(4):
i = 4 * c
a0, a1, a2, a3 = state[i:i + 4]
t = a0 ^ a1 ^ a2 ^ a3
out[i + 0] = a0 ^ t ^ xtime(a0 ^ a1)
out[i + 1] = a1 ^ t ^ xtime(a1 ^ a2)
out[i + 2] = a2 ^ t ^ xtime(a2 ^ a3)
out[i + 3] = a3 ^ t ^ xtime(a3 ^ a0)
return [x & 0xFF for x in out]
def add_round_key(state, round_key):
"""轮密钥异或"""
return [(a ^ b) & 0xFF for a, b in zip(state, round_key)]
def rot_word(word):
"""字循环:abcd -> bcda"""
return word[1:] + word[:1]
def sub_word(word):
"""对 4 字节字做 SBOX 替换"""
return [SBOX[b] for b in word]
def key_expansion(key: bytes):
"""
AES-128 密钥扩展
输入:16字节 key
输出:11 轮轮密钥,每轮 16 字节
"""
if len(key) != 16:
raise ValueError("AES-128 的 key 必须是 16 字节")
key_bytes = list(key)
words = [key_bytes[i:i + 4] for i in range(0, 16, 4)] # 先拆成4个字
for i in range(4, 44):
temp = words[i - 1][:]
if i % 4 == 0:
temp = sub_word(rot_word(temp))
temp[0] ^= RCON[i // 4]
new_word = [(words[i - 4][j] ^ temp[j]) & 0xFF for j in range(4)]
words.append(new_word)
round_keys = []
for r in range(11):
rk = []
for i in range(4):
rk.extend(words[4 * r + i])
round_keys.append(rk)
return round_keys
def aes128_encrypt_block(block: bytes, round_keys):
"""
AES-128 单块加密
输入必须是 16 字节
"""
if len(block) != 16:
raise ValueError("单块长度必须是 16 字节")
state = list(block)
# 初始轮
state = add_round_key(state, round_keys[0])
# 中间 9 轮
for rnd in range(1, 10):
state = sub_bytes(state)
state = shift_rows(state)
state = mix_columns(state)
state = add_round_key(state, round_keys[rnd])
# 最后一轮:没有 MixColumns
state = sub_bytes(state)
state = shift_rows(state)
state = add_round_key(state, round_keys[10])
return bytes(state)
def aes128_ecb_encrypt(data: bytes, key: bytes) -> bytes:
"""
AES-128 ECB 加密
自动做 PKCS#7 补位
"""
round_keys = key_expansion(key)
data = pkcs7_pad(data, 16)
out = b""
for i in range(0, len(data), 16):
block = data[i:i + 16]
out += aes128_encrypt_block(block, round_keys)
return out
if __name__ == "__main__":
key = b"1234567890abcdef" # 16字节
pt = b"hello aes reverse"
ct = aes128_ecb_encrypt(pt, key)
print("key =", key)
print("pt =", pt)
print("ct(hex) =", ct.hex())
其他
Z3和迷宫以及一些爆破脚本没有固定板子,掌握运用方法即可在各类题型中乱杀了
Comments NOTHING