先来简述一下aes加密
参考
十分钟读懂AES加密算法_Lee.rw的博客-CSDN博客_aes加密
AES加密 - block2016 - 博客园 (cnblogs.com)
AES加密算法的详细介绍与实现_TimeShatter的博客-CSDN博客_aes加密
目录
1 密钥扩散
2 字节代替
3 行移位
4 列混淆
5 轮密钥加
在开始前,我们需要理解aes加密需要的三个步骤
1.混淆
在明文和加密之后的秘文之间建立某种关系是很好的想法。一个混淆的例子是凯撒密码。密文的每个字母对应于明文字母的后面第三个字母。
2.扩散
另一个很好的想法是扩散信息。一个例子是简单的列转置。
3.保密密钥
首先将数据放在一个4*4得矩阵里,在这个矩阵得末尾进行填充,因为数据不总是16字节来正好填满。这个矩阵我们在下文中称之为‘状态矩阵’。保密密钥也将放在4*4的矩阵中。
aes加密分为五个步骤
1.密钥扩散
2.字节代替
3.行移位
4.列混淆
5.轮密钥加
它是一种对称加密,即可逆,因为中间运用的是异或,简单又便于计算
异或和混淆交替进行使加密的安全性提高
异或即是一种对称加密算法
那我们从密钥扩散开始
1
初始的一轮将刚才我们创建的矩阵‘状态矩阵’和第一轮的密码4*4矩阵(初始密码矩阵)进行异或操作
密钥扩散过程
* 首先,将上一轮的密钥(密钥矩阵的第一列)的最后一列拿出来然后将这一列的第一个字节放到最后一个位置上,其他位置的字节依次向上移动一个位置
* 然后,将变换位置后的这一列通过一个替代盒的映射转换为另一列
* 然后把刚才的得到的那一列再与轮常量列(一个常量列)相异或,这个常量对每一轮都不一样(会随着异或而变化,第一次是初始)
* 最后再把刚才异或之后得到的列与上一轮的密钥的第一列(密钥矩阵的第一列)相异或得到第一列
刚才我们得到了第一列,那么第二列怎么得到呢?很简单,用我们上一轮的密钥的第二列和我们刚才得到的第一列异或就得到了新一轮的第二列,第三列第四列用同样的方法依次计算得到(注意256位的密钥更加复杂,我们用的是128位的密钥,也就是16字节)
接下来是中间轮了,中间轮是对一系列操作重复执行若干次。重复的次数取决于密钥的长度(128位则重复9次,192位重复11次,256位重复13次)
接着便是混淆
2
字节代替,也就是保证异或和混淆交替的混淆的一部分
混淆,映通过s盒,逆s盒实现一个字节到另外一个字节的映射,两种盒都为16*16的矩阵
这里不详细讲它的构造,因为我也看不懂
总之我们要把需要加密的内容将每一字节通过S盒换成另外一个字节。即将每一个字节的高四位作为行值,低四位作为列值,去找到s盒中对应的元素输出。
例如,加密时,输出的字节S1为0x12,则查S盒的第0x01行和0x02列,得到值0xc9,然后替换S1原有的0x12为0xc9。
在aes的简化魔改中往往会以明文的十进制形式作为下标去寻找s盒中的对应下标去作一个替换
3
接下来是行移位
行移位是一个简单的左循环移位操作。当密钥长度为128比特时,状态矩阵的第0行左移0字节,第1行左移1字节,第2行左移2字节,第3行左移3字节
4
列混淆
列混合变换是通过矩阵相乘来实现的,经行移位后的状态矩阵与固定的矩阵相乘,得到混淆后的状态矩阵。
5
最后一步是轮密钥加
轮密钥加是将128位轮密钥Ki同状态矩阵中的数据进行逐位异或操作,如下图所示。其中,密钥Ki中每个字W[4i],W[4i+1],W[4i+2],W[4i+3]为32位比特字,包含4个字节,他们的生成算法下面在下面介绍。轮密钥加过程可以看成是字逐位异或的结果,也可以看成字节级别或者位级别的操作。也就是说,可以看成S0 S1 S2 S3 组成的32位字与W[4i]的异或运算。
说的简单点,明文经过上述步骤后分为16一组,每个4*4矩阵与扩散后的密钥来异或,每次异或16个,一组与密钥异或完再换下一组,最后得到的就是密文。
举个魔改例子(是一道逆向破解简化魔改aes加密的题)
(level5)
for n in range(3):
result = cmp[16*n:16*(n+1)]
for i in range(50, -1, -1):
count = i*16
result = row(result)
result = resbox(result)
for j in range(16):
result[j] ^= a2[count]
count += 1
vi1 = vi[16*n:16*(n+1)]
for i in range(len(result)):
result[i] ^= vi1[i]
result = [chr(i) for i in result]
print(''.join(result), end='')
上面的数据和函数定义都省略了,简单的看一下就可以
首先明文是48字节的,扩展后的密钥800个字节。
先把48位的字节分为三组,800个字节也以16字节为一组,把明文每组这16个字节轮流与800个字节分组后的50组全部异或一遍,再换48位明文的第二组与800字节的密钥继续异或,最后得到的就是密文。(题中是逆向解密)
连接起来输出就可以了~