🔐 

单表替换

所有的单表替换都有个共同的特性:就是明密文一一对应。

典型例子就是 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)




最后修改:2025 年 04 月 21 日
如果觉得我的文章对你有用,请随意赞赏