这篇文章是 对我的上一篇博文的延续,之前讲解了 AxCrypt的安装于环境配置,这一章就开始谈谈其内部算法的实现。下面一篇是对其加密部分的讲解。
Rijndael算法是一种对称的密码算法。它允许可变动的数据区块及金钥的长度。数据块与金钥长度的变动是各自独立的。块长和密钥长度可以分别指定程128、192或者256位。其在某些操作是在字节级上定义的。字节表示有限字段GF(2^8)中的元素,一个字节中有8位。其他操作都根据4字节来定义。程序的功能架构如图1-1所示:
图1-1 程序功能流程
一、程序的输入数据
在Rijndael算法中,外部输入数据有两部分构成,一个是State、一个是Cipher Key。State是运算过程中锁产生的中间值,是一个4xNb的矩阵,Nb由数据长度除以32位求得,其实际的操作结果是把输入数据分割成了Nb个区块。Cipher Key是用来加密的密钥,也是一个4xNk的矩阵,Nk可由密钥长度除以32位求得,与State类似,实际的操作结果是把密钥分割成Nk个32位的子密钥。
在操作过程中,数据均用十六进制表示法表示,例如:
32 = 00110010(1 byte)
在程序执行部分,主要分为两大部分:1、加密操作2、密钥编制
二、加密操作
在这里的加密操作的对象就是上面介绍的State,按照该算法的标准文档可知,加密算法可以简单的描述为先将State进行AddRoundKey操作,而后经过多次的循环转置操作(包括:SubBytes操作、ShiftRows操作、MixColumns操纵、AddRoundKey操作),进行的次数Nr由上面提到的Nb和Nk来共同决定,具体如表2-1所示。
表2-1 Nr取值表
Nr |
Nb = 4 |
Nb = 6 |
Nb = 8 |
Nk = 4 |
10 |
12 |
14 |
Nk = 6 |
12 |
12 |
14 |
Nk = 8 |
14 |
14 |
14 |
通过上表我们很容易得知对我我们的128位的操作,所进行的次数为10次。程序的大概执行框架图如图2-1所示。
图2-1 程序执行框架图
程序的执行流程图与程序执行框架图类似,如图2-2所示
图2-2 加密部分程序流程图
下面就对该部分中的Transformations算法一一介绍。
1、1-SubBytes算法
1-SubBytes也叫做字节取代转换,是一个以字节为单位的非线性取代运算,取代表(S-Box)是经过两个运算过程而建立的。而且是可逆的。以下所说的运算数据是State与Cipher Key通过异或运算获得的。(异或运算可表示为(a^b)=(a’and b) or (a and b’))这里用Data表示,在改运算中是通过Data在S-Box中的一个映射进行的,用S-Box对应的坐标中的数值取代Data中的数值,例如在Data中的一个数值是十六进制的19,则在S-Box中X坐标就为1,Y坐标就为9。则在S-Box中对应坐标的数值为d4,依次类推,将这个4xNr的矩阵中每个数值都进行映射替换。
2、2-ShiftRows算法
该操作也即为移位转换操作。在这个转换中Data(其实也就是State)的每一列以不同的偏移量做环状位移,第0列不动,接下来的几列按照Nb的大小进行相应的移位操作,我们现在的Nb=4,所以第1列移位1位,第2列移位2列,第3列移位3位。该移位是循环左移操作。具体的偏移量与区块数目Nb的关系如表2-2所示。
Nb |
C1 |
C2 |
C3 |
4 |
1 |
2 |
3 |
6 |
1 |
2 |
3 |
8 |
1 |
3 |
4 |
3、3-MixColumns算法
该部分算法实则是一个混行转换算法,将Data(也即State)中的每一列单列出来,与一个固定的多项式进行乘法运算。
固定的多项式为:02 03 01 01
0102 03 01
0101 02 03
0201 01 02
在这部分就要涉及到一个多项式问题。假设一个字节b由b7b6b5b4b3b2b1b0组成,那么就可以将其表示成为一个多项式形式:b7*x7+b6*x6+b5*x5+b4*x4+b3*x3+b2*x2+b1*x+b0.
多项式的乘法:在乘法里面,多项式相乘之后的结果很容易造成溢位的问题,解决溢位的方式是把相乘的结果,再模余一个不可分解的多项式m(x)。在Rijndael中,定义一个这样子的多项式为
m(x)=x8+x4+x3+x+1或是(11B)16
将Data也即State)中的每一列都进行同样胡操作。
4、4-AddRoundKey算法
该部分主要是把每一个回合的子密钥通过与Data(也即State)位异或操作。可以以列的形式将Data中的数值与子密钥进行异或运算。有关每一个回合的子密钥来说在第三部分将会详细介绍。
一、密钥的编制(Key Schedule)
回合子密钥(Round Key)是从加密密钥(Cipher Key)经过运算产生出来的。密钥编制(Key Schedule)是由密钥扩充(Key Expansion)及回合密钥的选择(RoundKey Selection)组成的,基本的理论如下:
所有回合密钥的总位数是把区块长度(block length)乘上回合数加1,(有Nr-1个回合,加上一个终止回合(final round)),例如,128个位的区块长度经过10个回合运算,所需要用到的所有回合密钥的总位数为1408个位。
加密密钥(Cipher Key)必须扩充为扩充密钥(Expanded Key)。
回合金钥是从扩充金钥中选出来的,选择的方式如下:第一个回合金钥由前Nb个字组组成,第二个回合金钥由接下来的Nb个字组组成,余此类推。
在该部分首先将Cipher Key中的第四列提取出来,将其循环下移一位(可以理解成将这一列数据旋转成为一行,而后对其循环右移一位),而后将该列进行1-SubBytes运算,与S-Box矩阵进行映射置换操作,接着将其结果与第一列以及回合常数进行异或操作。这边生成了第一回合的第一列子密钥,而后第二列与第一回合第一列子密钥进行异或运算后生成第一回合的第二列子密钥,一次类推,第三列与第二回合的第二列子密钥异或运算,得到第一回合的第三列子密钥等。接下来的第二轮回合则是拿第一回合的子密钥进行相同操作的。知道进行Nr次以后。回合常数如表3-1所示。
表3-1 回合常数
01 |
02 |
04 |
08 |
10 |
20 |
40 |
80 |
1b |
36 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
而后接下来的便是sha-1算法了,有关sha-1算法的介绍在我之前的博文http://yiluohuanghun.blog.51cto.com/3407300/950450中有所介绍。
本文转自 驿落黄昏 51CTO博客,原文链接:http://blog.51cto.com/yiluohuanghun/1211182,如需转载请自行联系原作者