AES加密算法的C++实现
扫描二维码
随时随地手机看文章
摘要:作为新一代的加密标准,AES 旨在取代 DES(请看《DES加密算法的C++实现》),以适应当今分布式开放网络对数据加密安全性的要求。本文在分析了
AES 加密原理的基础上着重说明了算法实现的具体步骤,并用 C++ 实现了对文件的加密和解密。
一、AES 介绍
AES(高级加密标准,Advanced Encryption Standard),在密码学中又称 Rijndael 加密法,是美国联邦政府采用的一种分组加密标准。这个标准用来替代原先的 DES,目前已经广为全世界所使用,成为对称密钥算法中最流行的算法之一。
在 AES 出现之前,最常用的对称密钥算法是DES 加密算法,它在 1977 年被公布成为美国政府的商用加密标准。DES 的主要问题是密钥长度较短,渐渐不适合于分布式开放网络对数据加密安全性的要求。因此,1998年美国政府决定不再继续延用 DES 作为联邦加密标准,并发起了征集 AES 候选算法的活动。征集活动对 AES 的基本要求是: 比三重DES快、至少与三重DES一样安全、数据分组长度为128比特、密钥长度为128/192/256比特。
经过三年多的甄选,比利时的密码学家所设计的 Rijndael 算法最终脱颖而出,成为新一代的高级加密标准,并于 2001 年由美国国家标准与技术研究院(NIST)发布于FIPS PUB 197。
二、AES 算法原理
AES算法(即 Rijndael 算法)是一个对称分组密码算法。数据分组长度必须是128 bits,使用的密钥长度为128,192或256 bits。对于三种不同密钥长度的 AES 算法,分别称为“AES-128”、“AES-192”、“AES-256”。(Rijndael 的设计还可以处理其它的分组长度和密钥长度,但 AES 标准中没有采用)
下图是 AES 加密解密的整体流程图:
这里我们需要知道3个符号:Nb
—— 状态 State 包含的列(32-bit 字)的个数,也就是说 Nb=4;Nk
——
密钥包含的 32-bit 字的个数,也就是说 Nk=4,6 或 8;Nr
—— 加密的轮数,对于不同密钥长度,轮数不一样,具体如下图所示:
下面分为密钥扩展、分组加密、分组解密三个部分来讲 AES 算法,我会尽可能地简明扼要,若还有不懂的,请自行 Google。
1)密钥扩展
AES 算法通过密钥扩展程序(Key Expansion)将用户输入的密钥 K 扩展生成Nb(Nr+1)
个字,存放在一个线性数组w[Nb*(Nr+1)]
中。具体如下:
位置变换函数RotWord()
,接受一个字 [a0, a1, a2, a3] 作为输入,循环左移一个字节后输出 [a1, a2, a3, a0]。
S盒变换函数SubWord()
,接受一个字 [a0, a1, a2, a3] 作为输入。S盒是一个16x16的表,其中每一个元素是一个字节。对于输入的每一个字节,前四位组成十六进制数
x 作为行号,后四位组成的十六进制数 y 作为列号,查找表中对应的值。最后函数输出 4 个新字节组成的 32-bit 字。
轮常数Rcon[]
,如何计算的就不说了,直接把它当做常量数组。
扩展密钥数组w[]
的前 Nk 个元素就是外部密钥 K,以后的元素w[i]
等于它前一个元素w[i-1]
与前第
Nk 个元素w[i-Nk]
的异或,即w[i]
= w[i-1] XOR w[i-Nk]
;但若 i 为 Nk 的倍数,则w[i] = w[i-Nk] XOR SubWord(RotWord(w[i-1]))
XOR Rcon[i/Nk-1]
。
注意,上面的第四步说明适合于 AES-128 和 AES-192,详细的伪代码如下:
密钥扩展程序的 C++ 代码(AES-128):
[cpp]view plaincopy #include