🔐
单表替换
所有的单表替换都有个共同的特性:就是明密文一一对应。
典型例子就是 Caesar(恺撒)密码:
明文:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
密文:
DEFGHIJKLMNOPQRSTUVWXYZABC
这里的偏移量是 3。
根据偏移量的不同,还存在若干特定名称的变种:
偏移量为 10:Avocat(A → K)
偏移量为 13:ROT13
偏移量为 -5:Cassis(K6)
偏移量为 -6:Cassette(K7)
🔁
仿射密码
Affine Cipher
加密函数
给定参数 a、b、模数 m,加密函数为:
E(x) = (a * x + b) mod m
其中:
- x:明文字符转换成的数字(通常从 0 开始,比如 A=0, B=1, ..., Z=25)
- a:必须与 m 互质(即 gcd(a, m) = 1),才能解密
- b:偏移量
- m:字母表大小(如英文为 26)
解密函数
解密时需要 a 在模 m 下的乘法逆元 a⁻¹,满足:
a * a⁻¹ ≡ 1 (mod m)
解密函数为:
D(x) = a⁻¹ * (x - b) mod m
Python
实现
加密函数
def encrypt(text, a, b, m):
encrypt = ""
for i in text:
x = ord(i) - ord('a')
y = (a * x + b) % m
encrypt += chr(y % 26 + ord('a'))
return encrypt
test1 = encrypt("hello", 3, 5, 26)
print(test1)
# armmv
解密函数
def decrypt(text, a, b, m):
decrypt = ""
a = pow(a, -1, m)
for i in text:
x = ord(i) - ord('a')
y = (a * (x - b)) % m
decrypt += chr(y % 26 + ord('a'))
return decrypt
test2 = decrypt("armmv", 3, 5, 26)
print(test2)
# hello
🎯 CTF
实战:
TWCTF 2016 - super_express
import sys
key = '****CENSORED***************'
flag = 'TWCTF{*******CENSORED********}'
encrypted = '805eed80cbbccb94c36413275780ec94a857dfec8da8ca94a8c313a8ccf9'
if len(key) % 2 == 1:
print("Key Length Error")
sys.exit(1)
n = len(key) // 2
encrypted = ''
for c in flag:
c = ord(c)
for a, b in zip(key[:n], key[n:2*n]):
c = (ord(a) * c + ord(b)) % 251
encrypted += '%02x' % c
print(encrypted)
每轮变换形式如下:
c_i = (a_i * c_{i-1} + b_i) mod 251
是标准的仿射变换,每轮逆变换为:
c_{i-1} = a_i^{-1} * (c_i - b_i) mod 251
计算第一轮的
a
和
b
已知前两个字符的明文与密文:
c_0 = (a * p_0 + b) mod 251
c_1 = (a * p_1 + b) mod 251
Δc = a * Δp mod 251
a = Δc * (Δp)^(-1) mod 251
利用
Python
解密
import gmpy2
key = '****CENSORED*'
flag = 'TWCTF{*******CENSORED********}'
data = '805eed80cbbccb94c36413275780ec94a857dfec8da8ca94a8c313a8ccf9'
encrypted = [int(data[i:i+2], 16) for i in range(0, len(data), 2)]
plaindelta = ord(flag[1]) - ord(flag[0])
cihperdelta = encrypted[1] - encrypted[0]
a = gmpy2.invert(plaindelta, 251) * cihperdelta % 251
b = (encrypted[0] - a * ord(flag[0])) % 251
a = gmpy2.invert(a, 251)
result = ""
for c in encrypted:
result += chr((c - b) * a % 251)
print(result)