CTF—crypto
解题思路来自:i春秋的大佬们
https://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=52687&highlight=CTF
希尔密码是一种与矩阵相关的替换密码,只涉及基本的矩阵原理。
说起来还是挺简单的。
A-Z对应0-25,用作加密的矩阵(即密钥)必须是可逆的,否则就不可能译码。只有矩阵的行列式和26互质,才是可逆的。将数字写成与密钥相同或者是题目提示的形式,与密钥相乘得到密文,等于密文与26取模运算
密钥 X 明文 = 密文 (mod 26)
根据线性代数的知识:密钥 = 明文的逆矩阵 X 密文 (mod 26)
接下来求逆矩阵:逆矩阵 = 伴随矩阵 / 行列式
伴随矩阵是除该位元素外其他元素的代数余子式
下面是实验吧的一个题目,hillissoeasy
#conding:utf-8
from numpy import *
key=mat([[1,2],[0,1]])
key1=key.I.T
#密钥经过一次逆运算再做一次转置
finalans=''
#print key1
str='dloguszijluswogaqy'
#密文
str2=[0 for i in range(len(str))]
for i in range(len(str)):
str2[i]=ord(str[i])-ord('a')+1
#将字符串转换为hill密码中的数字
num=len(str2)%4
for i in range(4-num):
str2.append(0)
#print str2
#给上面得到数字进行补位,保证可以四个为一组,方便后面的计算
count=0
for i in range(len(str2)/4):
crypto1=mat([[str2[count],str2[count+1]],[str2[count+2],str2[count+3]]])
#以4个为一组,分别取出每一组密文
ans=(crypto1*key1)%26
#计算明文
ans2=array(ans)
#这里的array是将ans转化为矩阵的标准形式,从而可以去出每一个数字
count+=4
for m in range(2):
for n in range(2):
finalans+=chr(int(ans2[m][n])+ord('a')-1)
#将明文转化为字符串
print finalans
2x2的示例:
关键字hill转换成2x2密钥矩阵,
明文矩阵:(明文:shortmessage)
s o t e s g
h r m s a e
18 14 19 4 18 6
7 17 12 18 0 4
依此对明文列向量使用矩阵乘法
计算规则是:
最后讲解一道例题:
密文: AUJPSOADUIWAAMYOKQNTRLKY 明文中包含 BABYHILLS
在mod 26的情况下
明文的逆矩阵等于明文的伴随矩阵除以明文的行列式
已知密文和部分明文,不确定明文对应的密文,所以尝试组合所有可能性,一共是16种可能性,由于很多可能性mod 26是不可逆的,就可以排除。
得到AUJPSOADU 对应BABYHILLS ,密钥为ZXYXUABXL
最后得到flag:BCNS {BABYHILLSISSOEASYAMAZING}