概述
本来想把本身AES加密算法的整个实现过程给详细复述下来,分享给想学习的同窗,也方便本身复习,但后来发现该工做量太大,加上做业太多没有过多的时间去写。因此就想把本身在学习的过程当中多遇到的好的文章进行汇总,避免重复性的工做,由于我感受有的文章的介绍和配图写的很是好,再次重复也没有意义。本文里我会将文章的连接附上,若有侵权,敬请告知!html
由于最近要完成课程做业,实现AES128加解密,本觉得就是一个简单的算法实现,后来发现AES加密的每一步都挺难,并且都涉及到我没听过的概念,因此最近看了不少帖子、资料。最终终于可以解决这个问题。关于AES算法的介绍,网上有不少的帖子,因此我就不进行赘述了,我只是但愿将我遇到的一些比较难以理解的点进行详细的叙述。git
实现AES算法主要包括如下学习步骤:github
-
- GF(2^8)域上的多项式运算
- 扩展的欧几里德算法
- 生成S盒
- 生成逆S盒
- S盒置换
- 行移位
- 列混合
- 生成秘钥
- 循环加密
其中一、二、三、4步都跟S盒生成有关,根据我所看的一些博客,S盒的生成涉及到数论的基础知识。若是没有基础的话,一、2是要专门去学习的,我在这两步上花费了不少时间。可是在网上也能够找到不少AES算法,他们用的是现成的S盒,没有前4步,直接用现成的S盒置换,这样相对会容易一些。可是本着刨根问底和多学习知识的原则,我仍是去学习了S盒的生成方式。第5步就是将每个字符进行查表替换,没有什么难以理解的地方,因此相对而言比较容易。第6步应该是整个过程中最简单的一步了,就是进行一个循环移位。第7步列混合涉及到矩阵和多项式的乘法,因此仍是有必定难度,。。。算法
若是想从总体上了解AES加密的完整过程,那么下面几篇文章无论从叙述仍是插图上来看都是很不错的,几篇文章介绍的方式不一样,可是原理都是同样的,对比结合着看会更有帮助:shell
http://www.javashuo.com/article/p-majyrkax-cn.html函数
https://blog.csdn.net/u012721519/article/details/79612128学习
http://www.javashuo.com/article/p-dujtalqt-ca.html加密
http://www.alonemonkey.com/2016/05/25/aes-and-des/spa
可是仅从这几篇文章来看的话,对于像我这样的小白而言仍是没有办法实现的,由于各个步骤介绍的并不具体,尤为是对于缺乏基本数学知识学习的同窗很难理解。因此这几篇文章能够做为总体进度的把控,接下来看怎么一步步学习实现。.net
S盒
我在学习这个算法的时候,在S盒的生成及置换上花费的时间是最多的。多是由于基础较差,因此须要学习的东西比较多,因此我将这一部分进行了逐项的划分。关于S盒的生成及置换,这篇博客进行了很是详细的介绍,可是有一些东西我仍是没明白,因此又参考了不少其余文章,才把这一部分搞明白。建议初学者以这篇博客为基础进行学习:
https://blog.csdn.net/u011516178/article/details/81221646
下面进行分步的介绍。
GF(2^8)域上的多项式计算
由于整个过程不少,因此我决定分为多个文章分别进行叙述,首先是GF(2^8)域上的多项式计算,由于之前也没有学过相关知识,不少概念都是第一次见到,因此这部分花了很长时间去学习。在学习这个以前,咱们须要知道为何去学习这个东西,AES加密中的哪一步用到了该知识点呢?
S盒的置换就是将0~2^8中的任意一个字节置换为另一个,置换的原则是将该元素置换为在GF(2^8)域上的乘法逆元,什么是GF(2^8)域?什么又是逆元呢?这些定义的准确数学描述我不太懂,根据本次应用,我能够给出粗略说明,GF(2^8)有限域大概就是指定义在该域中的数值通过定义在该域上的函数运算,其结果也都在该域内, 借用网上的一个例子进行说明:
那什么又是乘法逆元呢,形如:
其中p为有限域的范围,这里按理说应该为2^8,可是却不能取这个数,由于2^8并不与其内的每个数互质,因此只能选一个更大的质数(具体缘由请参考扩展的欧几里德算法),AES算法中p的值选的是0x11B, 我也不知道为何,多是约定俗成的吧,由于若是想找一个稍微比255大的质数,不知道为何要取293(0x11B)。 为有限域内的整数,那么
即为
在有限域上的逆元。至此,咱们知道逆元是什么,可是具体怎么去求解还不太清楚,这一部分请参照扩展的欧几里德算法。(更新)后来为了加深学习,我又本身写了篇博客。
我接下来继续说GF(2^8)域上的多项式运算,由于把基本的运算搞清楚是计算GF(2^8)域上乘法逆元的前提,该域上的加减乘除运算是与传统的运算所不一样的,具体的多项式运算请参考GF(2^8)域上的多项式运算。固然,也能够先学习扩展的欧几里德算法,而后再学习该部分,实现的时候将欧几里德算法中的四则运算换成GF(2^8)域上的多项式运算就好了。关于GF(2^8)域的计算介绍参考如下几篇博客介绍:
https://blog.csdn.net/luotuo44/article/details/41645597
http://www.javashuo.com/article/p-axrshgwe-ng.html
http://abcdxyzk.github.io/blog/2018/04/16/isal-erase-3/
在四则运算中,加减运算就是简单的异或运算,很简单。而乘除运算则是以乘法运算为基础,因此四则运算中最主要的是理解乘法的运算,这篇http://www.javashuo.com/article/p-mxtchask-ng.html文章详细介绍了乘法运算,以及其实现。
拓展的欧几里得算法
待掌握了GF(2^8)域的运算知识后,应该去学一下拓展的欧几里得算法,对于该算法,上面所给出的关于S盒生成的综述博文里已经参考相关教材进行了很是详细的论述,因此关于这部分知识能够一样参考这篇博文(参考文献10),
还能够参考如下这篇博客:
https://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html
若是还不明白,也能够自行查找其余关于拓展欧几里得算法的介绍。
S盒生成及置换
关于S盒的生成及置换,一样参考文献10,该文章已经进行了很是详尽的描述与代码实现。待本身完成后也能够参考博客中的结果进行检验。
行移位
行移位就是对每行数据进行相应的循环移位,没有难以理解的地方,应该是整个加密过程最简单的部分,关于移位的规则,能够参考文献一、二、三、4,均有详细的图示介绍。下图来源于文献4:
列混合
列混合就是将数据矩阵乘上一个矩阵,解密的时候乘上原矩阵的逆矩阵进行解密,秩序要按照步骤一步步来便可,一样没有难以理解的地方,按照参考文献一、二、三、4的介绍进行操做就没有问题。关于列混合还能够参照这篇专门介绍的文章[11],其对于列混合又专门的介绍与实现,并且还有检验数据。下图参照文献4中图片:
密钥生成
密钥的生成过程稍微有些麻烦,须要仔细参考规则,避免搞错,可是只须要理解操做规则便可,不须要理论理解,还好参考文献三、4中都有很是生动的图示。下图来源于文献4:
循环加密
循环加密就是对上述过程重复进行若干次。具体实现参照文献一、二、三、4。
解密
解密过程就是将上述的过程反过来执行一遍,本来置换的就置换过来;本来移位的就反向移过来;本来乘上矩阵的就乘上她的逆矩阵。。。上面关于每一个加密过程的参考文献都有相应的解密过程。
实现
关于AES128的加密完整实现,能够参照代码https://github.com/xinyu-yang/AES128-CBC,此代码的实现几乎都是参照上文的介绍,惟一不一样的是在加密的时候采用了CBC模式,具体什么是CBC加密模式,若是不清楚的能够自行百度。若是有时间我也会把这部分补全。
参考文献:
一、https://blog.csdn.net/zhjchengfeng5/article/details/7786595
二、http://www.javashuo.com/article/p-majyrkax-cn.html
三、https://blog.csdn.net/u012721519/article/details/79612128
四、http://www.javashuo.com/article/p-dujtalqt-ca.html
五、http://www.alonemonkey.com/2016/05/25/aes-and-des/
六、https://blog.csdn.net/luotuo44/article/details/41645597
七、http://www.javashuo.com/article/p-axrshgwe-ng.html
八、http://abcdxyzk.github.io/blog/2018/04/16/isal-erase-3/
九、http://www.javashuo.com/article/p-mxtchask-ng.html
十、https://blog.csdn.net/u011516178/article/details/81221646
十一、https://blog.csdn.net/u012620515/article/details/49893905
十二、https://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html