七叶笔记 » java编程 » AES加密算法的原理详解与实现分析

AES加密算法的原理详解与实现分析

1.密钥扩展的实现

在开始加密前,必须先获得第一轮加密用到的密钥,故先实现密钥扩展 下面是密钥扩展函数的实现,这个函数传入密钥key的字符串表示,然后从字符串中读取W[0]到W[3],函数getWordFromStr()用于实现此功能。读取后,就开始扩展密钥,当i是4的倍数的时候,就会调用T()函数来进行扩展,因为T函数的行为与加密的轮数有关,故要把加密的轮数 j 作为参数传进去。

下面是T()函数的代码实现,T()函数中接收两个参数,参数num为上面传进的W[i - 1],round为加密的轮数。首先用一个numArray储存从32位的W[i-1]中取得4个字节。如果W[i-1]为0x12ABCDEF,那么numArray[0] = 0x12,numArray[1] = 0xAB。函数splitIntToArray()用于从32位整数中读取这四个字节,之所以这样做是因为整数数组比较容易操作。然后调用leftLoop4int()函数把numArray数组中的4个元素循环左移1位。然后执行字节代换,通过getNumFromSBox()函数来获取S盒中相应的值来替换numArray中的值。接着通过mergeArrayToInt()函数把字节代换后的numArray合并回32位的整数,在进行轮常量异或后返回。

2. 字节代换的实现

字节代换的代码很简单,就是把状态矩阵中的每个元素传进getNumFromSBox()函数中,然后取得前面8位中的高4位作为行值,低4位作为列值,然后返回S[row][col],这里的S是储存S盒的数组。

3.行移位的实现

行移位的时候,首先把状态矩阵中第2,3,4行复制出来,然后对它们行进左移相应的位数,然后再复制回去状态矩阵array中。

4.列混合的实现

列混合函数中,先把状态矩阵初始状态复制一份到tempArray中,然后把tempArray与colM矩阵相乘,colM为存放要乘的常数矩阵的数组。其中的GFMul()函数定义了矩阵相乘时的乘法,加法则直接通过异或来实现。GFMul()通过调用乘以各个数对应的函数来实现乘法。例如,S1 * 2 刚通过调用GFMul2(S1)来实现。S1 * 3 刚通过GFMul3(S1)来实现。在这里,主要实现GFMul2()函数就行了,其它的都可以通过GFMul2()的组合来实现。举个例子吧,为计算下面这条等式,需要像下面这样调用函数

s = GFMul3(0xC9) ^ 0x7A ^ 0x63 ^ GFMul2(0xB0)

5.轮密钥加的实现

轮密钥加的实现很简单,就是根据传入的轮数来把状态矩阵与相应的W[i]异或。

AES解密函数

AES的解密函数和加密函数有点不同,可以参考上面的等价解密流程图来理解,解密函数中调用的是各轮操作的逆函数。逆函数在这里就不详细讲解了,可以参考最后的完整代码。

完整的程序代码 Linux版本 aes.h aes.c main.c

通过下面的gcc命令来编译运行:

VC6.0版本

由于VC6.0的编译器比较坑,要先声明,后使用变量,故要对代码进行相应的修改。

aes.h aes.cpp

有不少初学者可能在使用AES实现的VC版本时,会出现没main函数的问题。其实直接导入VC编译是不行的,这里给出的只是头文件 aes.h 和实现的 aes.cpp 文件,需要通过include来包含使用,假设main函数所在的文件 main.cpp,并且与 aes.h 、 aes.cpp 文件在同一目录下,则需要像下面这样使用:

很高兴这篇文章能给大家带来帮助,我现在主要做信息安全方面的工作。下面是我创建的公众号,会不定期分享一些信息安全方面的技术文章,欢迎关注~

相关文章