GKCTF2020 小学生的密码学
题目
e(x)=11x+6(mod26)
密文:welcylk
(flag为base64形式)
求解
- 这种形式的加密手法是仿射变换,其加解密分别是\(^{[1]}\):
\[c=E_{a,b}(m)=am+b\ (mod\ 26)
\]
\[m=D_{a,b}(c)=a^{-1}(c-b)\ (mod\ 26)
\]
- 所以可以得到\(a=11, b=6\),需要做的工作是根据\(密文c, 密钥a/b\)求得明文\(m\)。这里\(a^{-1}\)计算可以利用Python的gmpy2库中invert函数完成
- 注意仿射变换26个字母按数字0~25记,因此在需要将密文ASCII对应的数值减去97,解密完恢复成字母即加上97
- 此外,题目要求最后的flag为base64形式,因此还需借助Python的base64库中b64encode函数。需要注意的是在Python3中,字符都为unicode编码,而b64encode函数的参数为byte类型,所以必须先转码\(^{[2]}\)。
- 解题代码如下
from gmpy2 import invert
from base64 import b64encode
c = "welcylk"
a = 11
b = 6
n = 26
in_a = invert(a, n)
print(in_a)
# in_a = 19
m = []
for i in c:
modified_c = ord(i)-97
m.append((modified_c-b)*in_a % 26)
flag = ""
for mi in m:
flag += chr(mi+97)
print(b64encode(flag.encode()))
flag
参考
[1] 《现代密码学》第四版,第一章第四节
[2] https://blog.csdn.net/fireflylane/article/details/84674509