从零开始的勇士之路 - Writeup by AI
一、题目信息
- 题目来源:Bugku Crypto
- 题目名称:从零开始的勇士之路
- 题目类别:密码学 / 仿射密码
二、考点分析
| 考点 | 权重 | 说明 |
|---|---|---|
| 仿射密码原理 | 40% | 理解线性同余加密机制 |
| 已知明文攻击 | 30% | 利用已知部分明文推导密钥 |
| 模逆元计算 | 20% | 理解解密所需的数学条件 |
| 参数枚举验证 | 10% | 小空间暴力搜索 |
知识点
- 仿射密码(Affine Cipher):一种单表代换密码,使用线性函数进行加密
- 加密公式 :C=(P×a+b)mod 26C = (P \times a + b) \mod 26C=(P×a+b)mod26
- 解密公式 :P=((C−b)×a−1)mod 26P = ((C - b) \times a^{-1}) \mod 26P=((C−b)×a−1)mod26
- 约束条件 :aaa 必须与 26 互质(即 gcd(a,26)=1\gcd(a, 26) = 1gcd(a,26)=1),否则不存在逆元
三、解题思路
1. 题目分析
- 密文 :
SNFFLKU{D_4p_ka3_aRe0_0u_Ka3_LezykV_tvEmo} - 已知明文 :
NUAACTF(CTF 比赛常见 flag 前缀) - 加密方式 :仿射密码(从
dec()函数可以判断)
2. 攻击策略
由于已知部分明文和对应密文,可以采用已知明文攻击:
- 建立方程组:Ci=(Pi×a+b)mod 26C_i = (P_i \times a + b) \mod 26Ci=(Pi×a+b)mod26
- 枚举所有可能的 (a,b)(a, b)(a,b) 组合
- 验证哪组参数能满足所有已知的明密文对
- 使用找到的参数解密完整密文
3. 技术路线
已知明文 → 建立方程 → 枚举参数 → 验证匹配 → 解密全文
四、详细步骤
步骤 1:分析加密算法
从提供的 dec() 函数可以看出这是仿射密码的解密实现:
python
def dec(m, a, b):
if m not in string.ascii_lowercase + string.ascii_uppercase:
return m
table = string.ascii_lowercase if m in string.ascii_lowercase else string.ascii_uppercase
return table[((table.index(m) - b) * inverse(a, 26)) % 26]
步骤 2:建立方程组
对于前 7 个字符:
- P='NUAACTF'P = \text{'NUAACTF'}P='NUAACTF' → 数值:[13, 20, 0, 0, 2, 19, 5]
- C='SNFFLKU'C = \text{'SNFFLKU'}C='SNFFLKU' → 数值:[18, 13, 5, 5, 11, 10, 20]
需要找到 (a,b)(a, b)(a,b) 使得:(Pi×a+b)mod 26=Ci(P_i \times a + b) \mod 26 = C_i(Pi×a+b)mod26=Ci
步骤 3:枚举参数
python
for a in range(1, 26):
for b in range(26):
# 检查 a 是否有逆元
try:
inverse(a, 26)
except:
continue
# 验证参数
match = True
for i in range(7):
P = ord(flag_prefix[i]) - ord('A')
C = ord(cipher[i]) - ord('A')
if (P * a + b) % 26 != C:
match = False
break
if match:
print(f"找到参数:a={a}, b={b}")
步骤 4:解密结果
运行脚本得到:
- 参数 :a=3,b=5a = 3, b = 5a=3,b=5
- Flag :
NUAACTF{XXX}
五、完整代码
solve.py
python
import string
from Crypto.Util.number import *
def dec(m, a, b):
"""仿射密码解密函数"""
if m not in string.ascii_lowercase + string.ascii_uppercase:
return m
table = string.ascii_lowercase if m in string.ascii_lowercase else string.ascii_uppercase
return table[((table.index(m) - b) * inverse(a, 26)) % 26]
# 已知信息
cipher = 'SNFFLKU{D_4p_ka3_aRe0_0u_Ka3_LezykV_tvEmo}'
flag_prefix = 'NUAACTF'
print("仿射密码(Affine Cipher)已知明文攻击")
print("=" * 60)
# 枚举参数 a 和 b
for a in range(1, 26):
for b in range(26):
try:
inverse(a, 26)
except:
continue
match = True
for i in range(len(flag_prefix)):
P = ord(flag_prefix[i]) - ord('A')
C = ord(cipher[i]) - ord('A')
if (P * a + b) % 26 != C:
match = False
break
if match:
print(f"[+] 找到参数:a={a}, b={b}")
# 解密整个密文
flag = ''
for char in cipher:
flag += dec(char, a, b)
print(f"[+] Flag: {flag}")
break
六、运行结果
============================================================
仿射密码(Affine Cipher)已知明文攻击
============================================================
[*] 正在枚举参数 a 和 b...
[+] 找到参数:a=3, b=5
[*] 使用参数 a=3, b=5 进行解密...
[+] 解密结果:NUAACTF{XXX}
============================================================
Flag: NUAACTF{XXX}
============================================================