本帖最后由 lanneret_sky 于 2011-03-03 07:59 编辑
1、AES加密算法简介
AES(The Advanced Encryption Standard),又称Rijndael加密法,该演算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijdael命名。是美国联邦政府采用的一种分块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的演算法之一。它被预期能成为人们公认的加密包括金融、电信和政府数字信息的方法。美国国家标准与技术研究所(NIST)在2002年5月26日建立了新的高级数据加密标准(AES)规范。
AES 是一个新的可以用于保护电子数据的加密算法。明确地说,AES 是一个迭代的、对称密钥分组的密码,它可以使用128、192 和 256 位密钥,并且用 128 位(16字节)分组加密和解密数据。与公共密钥密码使用密钥对不同,对称密钥密码使用相同的密钥加密和解密数据。通过分组密码返回的加密数据的位数与输入数据相同。迭代加密使用一个循环结构,在该循环中重复置换(permutations )和替换(substitutions)输入数据。
2、AES加密算法描述
AES 算法是基于置换和代替的。置换是数据的重新排列,而代替是用一个单元数据替换另一个。AES 使用了几种不同的技术来实现置换和替换,包括:S盒置换(SubBytes),行循环移位(ShiftRows),伽洛瓦域多项式运算,列混合预算。
2.1、分组(State)
密码运算的中间结果称为状态(State)。
State的表示:状态用以字节为基本构成元素的矩阵阵列来表示,该阵列有4行,列数记为Nb.
Nb=分组长度(bits)÷ 32
Nb可以取的值为4,6,8,对应的分组长度为128, 192, 256 bits。
2.2、密钥(Cipher Key)
Cipher Key类似地用一个4行的矩阵阵列来表示,列数记为Nk. Nk=密钥长度(bits)÷32
Nk可以取的值为4,6,8,对应的密钥长度为128, 192, 256 bits.
密钥扩展:密钥bit的总数=分组长度×(轮数Round+1)例如当分组长度为128bits和轮数Round为10时,轮密钥长度为128×(10+1)=1408bits。密钥的长度是够使用的,所以必须将密码密钥扩展成一个扩展密钥。扩展算法:第i-1轮的分组长度个字节的子密钥被分成4组来处理,每组4个字节。最后一组的4个字节先执行一个字节的循环左移,由S盒(这个S盒与字节替代时的S盒是一样的)来进行替代处理,然后这4个字节结果中的第一个字节和轮常数相异或,这个轮常数是预先定义的,并且固定值。最后,为了得到第i轮密钥,把得到的4个字节的结果和轮密钥的最初4个字节按位相异或,得到i轮密钥的最初4个字节,然后又和密钥的下面的4个字节按位相异或,得到i轮密钥的下面4个字节,以此类推。
2.2、SBox置换(SubBytes)
SBox称为S盒,它是一个16×16的固定值的矩阵。sbox置换法则:将需要置换的矩阵的每个字节的低4位作为s盒的纵坐标,将其高4位作为s盒的横坐标,使用这两个值取得对应的S盒中的值,作为置换后的值。
bytes[0] = AseSbox[ bytes[0] >> 4][bytes[0] & 0x0f ];
bytes[1] = AseSbox[ bytes[1] >> 4][bytes[1] & 0x0f ];
bytes[2] = AseSbox[ bytes[2] >> 4][bytes[2] & 0x0f ];
bytes[3] = AseSbox[ bytes[3] >> 4][bytes[3] & 0x0f ];
2.3、行循环移位(ShiftRows)
在行循环移位(ShiftRows)变换中,状态阵列的后3行循环移位不同的偏移量。第1行循环移位C1字节,第2行循环移位C2字节,第3行循环移位C3字节。
偏移量C1、C2、C3与分组长度Nb有关,如下表所示:
NB
| C1 | C2
| C3
| 4 | 1 | 2 | 3 | 6 | 1
| 2 | 3 | 8 | 1 | 3 | 4 |
2.4、伽洛瓦域运算(GF2
在GF(2 中用0x01的乘法是特殊的;它相当于普通算术中用1做乘法并且结果也同样—任何值乘0x01等于其自身。现在让我们看看用0x02做乘法。和加法的情况相同,理论是深奥的,但最终结果十分简单。只要被乘的值小于0x80,这时乘法的结果就是该值左移1比特位。如果被乘的值大于或等于0x80,这时乘法的结果就是用值0x1b异或后的值再左移1比特位。它防止了“域溢出”并保持乘法的乘积在范围以内。
一旦你在GF(2 中用0x02建立了加法和乘法,你就可以用任何常量去定义乘法。用0x03做乘法时,你可以将 0x03 分解为2的幂之和。为了用 0x03 乘以任意字节b,
因为 0x03 = 0x02 + 0x01,
因此:
b * 0x03 = b * (0x02 + 0x01)
= (b * 0x02) + (b * 0x01)
这是可以行得通的,因为你知道如何用 0x02 和 0x01 相乘和相加。
在AES加密中用到的计算代码如下:
Byte gfmultby01(const Byte b) { return b; } Byte gfmultby02(const Byte b) { return (b<< 1) ^ ff_tab[b >> 7]; } Byte gfmultby03(const Byte b) { return gfmultby02(b) ^ b ; } Byte gfmultby09(const Byte b) { return (gfmultby02(gfmultby02(gfmultby02(b))) ^b); }
Byte gfmultby0b(const Byte b) { return (gfmultby02(gfmultby02(gfmultby02(b))) ^gfmultby02(b) ^b ); }
Byte gfmultby0d(const Byte b) { return (gfmultby02(gfmultby02(gfmultby02(b))) ^gfmultby02(gfmultby02(b))^(b)); }
Byte gfmultby0e(const Byte b) { return(gfmultby02(gfmultby02(gfmultby02(b)))^gfmultby02(gfmultby02(b))^gfmultby02(b)); }
2.5、列混合运算(MixColumn)
MixColumn(列混合运算)将状态(State)的列看作是有限域GF(2 上的多项式a(x),与多项式c(x) = 03 x3 + 01 x2 + 01 x +02相乘(模x4+1)。
令b(x) = c(x) × a(x),写成矩阵形式为:
![]()
2.6、流程
3、AES加密的实现
代码加上后,系统告诉我内容过长,没法只好略去,想知道代码实现的请访问 http://www.greewater.com/view.asp?id=18
我的微博:http://t.sina.com.cn/kingbir 欢迎大家交流。 |