![cover](https://img-blog.csdnimg.cn/79a9246a210349c39e333d063968d660.jpeg)
AES算法基于FPGA的硬件实现(1)AES算法的原理以及实现流程
说明这个密钥托拓展过程,实际上不同的密钥长度对应的密钥拓展公式是不同的,比如当AES192的时候,密钥长度为6(32bit),如上图中W0-W3为初始密钥,然后W4-7为第一句轮密钥的数据,然后这里会根据K0以及密钥拓展算法来得到K1-K11,列混合是将输入的矩阵左乘这样一个固定的矩阵,但是这不是传统的矩阵相乘,需要按照有限域的运算规则来尽心运算。在执行过程中,每一轮的输入为上一轮的输出,比如第二
AES算法基本概念
- 为分组加密,五种模式ECB,CBC,CFB,OFB,CTR;
- 明文长度固定128位;
- 密钥长度可以为128、192、256位。
- 对称加密,解密为加密的逆过程。
- 计算规则为有限域GF(2⁸)的加法与乘法运算。
AES分组加密时每组16byte,执行完128bit后再进行下一组的加密。
一般明文分组使用字节为单位的正方形矩阵描述(状态矩阵)。
S0 | S4 | S8 | S12 |
---|---|---|---|
S1 | S5 | S9 | S13 |
S2 | S6 | S10 | S14 |
S3 | S7 | S11 | S15 |
与明文形成的状态矩阵相同,AES加密的密钥也是分组为字节为单位的矩阵(密钥矩阵)来表示。AES密钥长度对应不同的加密轮数。
AES | 加密轮数 | 初始密钥长度(32bit) |
---|---|---|
AES-128 | 10 | 4 |
AES-192 | 12 | 6 |
AES-256 | 14 | 8 |
AES加密执行过程(以AES-128为例,附带AES192/256的情况解释说明)
上图为AES-128为例,前9论为循环运算,第十轮为最终轮,在循环运算中步骤1-4全部执行,最终轮中不执行列混合。在循环运算开始之前需要执行密钥拓展和初始变换。 在执行过程中,每一轮的输入为上一轮的输出,比如第二轮进行字节代换的矩阵为第一轮进行轮密钥加后的结果。
1.密钥拓展和初始变换
1.密钥拓展详解
密钥拓展的过程是将16byte的初始密钥,此密钥矩阵设为k0,然后由初始密钥矩阵k0经过一系列变换之后得到k0-k10这11个密钥矩阵,其中第一个k0为初始密钥,用于对明文进行初始变换后面的10个密钥矩阵为轮密钥,用于后续运算的轮密钥加。
如上图中W0-W3为初始密钥,然后W4-7为第一句轮密钥的数据,然后这里会根据K0以及密钥拓展算法来得到K1-K11,密钥拓展基本公式如下(AES-128)。
可以看出,当i非4倍数的时候,可以直接进行。
AES-192/256的情况
上面只是以AES128为例说明这个密钥托拓展过程,实际上不同的密钥长度对应的密钥拓展公式是不同的,比如当AES192的时候,密钥长度为6(32bit),此时对应的公式为判断是否能整除6,同时此时的Wi-4也变为了Wi-6。
此公式为密钥拓展通用公式,
- 其中i<N表示轮密钥的前N列为原始密钥;
- 第二个公式为,i对N取余为0,对于AES128来说也就是4的倍数;
- 第三种情况为,i对N取余为4的情况发生,这种情况只会发生在AES256中,比如此时N=8,当i=12时胡发生这种情况(相比于情况2,少了轮常量异或和列位移);
- 其他非特殊情况均为第四个公式。
T函数的实现流程
-
字循环:对于每个格子上移一位。
-
字节代换:使用S盒(Substitution Box)来替代原始数据。
- 对于S盒,为固定数据且不可以改变,因为S盒内的数据经过设计的,而不是可以随意更改的,如果更改S盒内数据会降低算法的安全性和有效性。S盒如下图:
比如对于0x01,表示第0行第一列,此时对应S盒值为0x63.
- 轮常量异或:与Rcon(round constants)表进行异或操作。轮常量表如下:
轮常量计算公式以及说明
- 对于轮常量异或,下面为三种不同密钥长度下的一些理解:
- 当AES-128的情况下,由于要得到44组(32bit)的轮密钥,执行轮常量异或情况为10种;
- 在AES-192情况下,要得到52组(0-51)轮密钥,但是只有在为6的倍数的情况下,才会执行轮常量异或,所以总共会执行8次轮常量异或;
- 在AES-256下,会执行7次。
AES uses up to rcon_10 for AES-128 (as 11 round keys are needed), up to rcon_8 for AES-192, and up to rcon_7 for AES-256.(引自维基百科)
2.初始变换(轮密钥加)
初始变换为明文与初始密钥进行轮密钥加的操作。具体操作为对应位置进行异或操作,比如明文的第一行第一列数据会和初始密钥的第一行第一列的数据进行异或。
2.循环运算
1.字节替代
与密钥拓展中的字节代换相同,也是查S盒进行代换数据。
2.行位移
3.列混淆
列混合是将输入的矩阵左乘这样一个固定的矩阵,但是这不是传统的矩阵相乘,需要按照有限域的运算规则来尽心运算。
比如这里的第一个数据0x04,
是固定矩阵的第一行乘输入矩阵的第一列然后按照有限域运算规则来展开,
02*d4+03*bf+01*5d+01*30
=02*d4⨁03*bf⨁01*5d⨁01*30
02*d4=0x1c4>0x80->02*d4=(0x1c4 mod 0x100)⨁0x1b=0xc4⨁0x1b=0xb3 (1)
03*bf=02*bf⨁01*bf=((02*bf)mod 0x100)⨁0x1b⨁0xbf=0xda (2)
01*5d=0x5d
0x*30=0x30
0x5d⨁⨁0x30⨁0xda⨁0xb3=0x04
对于(1)(2)为什么这么计算主要是因为GF(2⁸)的运算规则
GF(2⁸)运算规则
这里的域(Field)的定义是有如下特性的集合:
- 定义了加法和乘法
- 集合内的元素经过加法和乘法计算,结果仍然在集合内
- 计算符合交换率、结合率、分配率
- 加法和乘法有单位元素(所有的集合内的值都有对应的负数,所有集合内非零值都有倒数)
这里的倒数和负数也不是传统意义上的倒数和负数,比如在GF(3)内按GF(3)运算规则来看:
1+2=3(mod 3)=0;//1和2互为负数
2*2=4(mod 3)=1;//此时2就是2的倒数
因为这里不是对有限域的问题进行讨论故对有限域的问题浅尝辄止
下面为AES运算的有限域的运算规则。
- 加法操作:加法直接按异或来执行;
- 乘法操作:假设一个函数f(a)=2*a,假设a<0x80(128),返回2*a,否则返回((2*a mod 0x100)⨁0x1B);
- 对于0x02*a=f(a),其他非0x02的数则转换为0x02
eg:0x10*a=f(0x08*a); - 对于非上述例子的2的N次方的数据,可以进行拆分相加的操作。
0x0d = 0x08+0x04+0x01->0x0d*a=0x08*a+0x04*a+0x01*a
然后将加号改为⨁,总之是将非2N次方的数分解为2的N次方的数来相加,最后把加号换为异或符号。
4.轮密钥加
与初始变换的算法相同,使用列混合数据(最后一轮不执行列混合)与不同轮密钥进行异或运算。
AES解密流程
因为AES加密是对称加密,所以解密就是加密的逆过程。
- 轮密钥加;
- 逆列混淆(因为加密时最后一轮不执行列混淆,所以解密第一轮不执行这个逆过程);
- 逆行位移;
- 逆字节代换。
在完成上面的循环逆过程后,执行轮密钥加第零轮(原始密钥)。
逆列混淆
逆列混淆仍然为左乘一个矩阵,但是这个矩阵与列混淆左乘矩阵不同,如下:
逆字节代换
逆字节代换执行的S盒为逆S盒,如下图:
逆行位移
行位移为左移,逆行位移为右移操作。
第一部分到这里就结束了,下面预计先进行C/C++的算法验证,最后进行Verilog的算法实现。
1参考文章:AES加密算法原理的详细介绍与实现
2参考链接:AES加密算法详解(图文解释)
3参考链接:AES key schedule
4参考链接:AES算法加密过程详细讲解-《信息安全》
5参考链接:AES加密和解密算法流程
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)