——2018.10.22
目录
1引言... 1
1.1任务概要... 1
1.2运行环境和开发环境... 1
1.3密码算法原理简单介绍... 1
2 程序各模块详细设计... 3
2.1核心模块主要实现算法的流程... 3
2.2 AES加密的算法说明和实现方式... 4
2.2.1字节代替(Subbyte)... 4
2.2.2行移位(ShiftRows)... 4
2.2.3列混合(MixColumns)... 5
2.2.4 轮秘钥加(AddRoundKey)... 7
2.2.5 秘钥扩展(KeyExpansion)... 7
2.3 AES解密的算法说明和实现方式... 8
2.3.1逆行移位(InvShiftRows)... 8
2.3.2逆字节代替(InvSubbyte)... 9
2.3.3逆列混合(InvMixColumns)... 10
3 程序测试... 10
3.1手动输入明文和秘钥测试过程... 10
3.2随机生成明文和秘钥测试过程... 11
3.3手动输入密文和秘钥测试过程... 12
4 密码算法课程设计实践总结... 13
5 参考文献... 14
- 随机产生n组128比特明文,加密产生n组128比特密文,密钥不变;b)操作简单,界面美观。
- 输入和输出要求:
- 用函数实现AES加密和解密
- 输入和输出的128比特明文和密文采用十六进制
- 要求至少有一组来自标准fips-197的测试。
- 随机产生的明文和加密后的明文(即密文)保存为txt文件,保存格式为每行记录一组明文和对应密文。如txt文件格式
明文:0xbce3 …… 密文:0x……
明文:0x…… 密文:0x……
加密密钥为:0x……
- 解密验证,从(4)中txt文件,获取任意一组密文和密钥,解密输出明文,并输出显示在屏幕上。
美国国家标准技术研究所在2001年发布了高级加密标准(AES)。AES是一个对称分组密码算法,旨在取代DES成为广泛使用的标准。根据使用的密码长度,AES最常见的有3种方案,用以适应不同的场景要求,分别是AES-128、AES-192和AES-256。本课题设计主要对AES-128进行介绍,另外两种的思路基本一样,只是轮数会适当增加。
■图1 AES算法流程图
如图1所示,AES加密过程涉及到4种操作:字节替(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥(AddRoundKey)。解密过程分别为对应的逆操作。由于每一步操作都是可逆的,按照相反的顺序进行解密即可恢复明文。加解密中每轮的密钥分别由初始密钥扩展得到。算法中16字节的明文、密文和轮密钥都以一个4x4的矩阵表示。
AES程序流程如图2所示
AES的字节代换其实就是一个简单的查表操作。AES定义了一个S盒和一个逆S盒。 状态矩阵中的元素按照下面的方式映射为一个新的字节:把该字节的高4位作为行值,低4位作为列值,取出S盒或者逆S盒中对应的行的元素作为输出。
// 字节代替
public byte[][] subbyte(byte[][] sub) {
byte row, col;
byte[][] temp = new byte[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
col = (byte) (sub[i][j] & 0xf);
row = (byte) ((sub[i][j] >> 4) & 0xf);
temp[i][j] = sbox[row][col];
}
}
return temp;
}
行移位是一个简单的左循环移位操作。当密钥长度为128比特时,状态矩阵的第0行左移0字节,第1行左移1字节,第2行左移2字节,第3行左移3字节,如图3所示:■图3 行移位示意图
// 行移位
public byte[][] shift(byte[][] sub) {
byte temp;
temp = sub[1][0];
sub[1][0] = sub[1][1];
sub[1][1] = sub[1][2];
sub[1][2] = sub[1][3];
sub[1][3] = temp;
temp = sub[2][0];
sub[2][0] = sub[2][2];
sub[2][2] = temp;
temp = sub[2][1];
sub[2][1] = sub[2][3];
sub[2][3] = temp;
temp = sub[3][0];
sub[3][0] = sub[3][3];
sub[3][3] = sub[3][2];
sub[3][2] = sub[3][1];
sub[3][1] = temp;
return sub;
}
列混合变换是通过矩阵相乘来实现的,经行移位后的状态矩阵与固定的矩阵相乘,得到混淆后的状态矩阵,如下图的公式所示:
■图4 AES列混合示意图
// 列混合
public byte[][] mix(byte[][] sub) {
byte count = 0;
byte[][] temp = new byte[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
while (count < 4) {
temp[i][j] = (byte) (temp[i][j] ^ mu(mut[i][count], sub[count][j]));
count++;
}
count = 0;
}
}
return temp;
}
// 列混合中所用函数
public byte mu(byte b, byte c) {
byte ret = 0, count1 = 0, count2 = 0;
byte[] barray = new byte[8];
byte[] carray = new byte[8];
byte[] pro = new byte[15];
if (b == 1 | c == 0)
return c;
if (c == 1)
return b;
for (int i = 0; i < 8 && b != 0; i++) {
barray[i] = (byte) (b & 1);
b = (byte) (b >> 1);
count1++;
}
for (int i = 0; i < 8 && c != 0; i++) {
carray[i] = (byte) (c & 1);
c = (byte) (c >> 1);
count2++;
}
for (int i = 0; i < count1; i++)
for (int j = 0; j < count2; j++) {
if (barray[i] > 0 & carray[j] > 0)
pro[i + j] = (byte) ((pro[i + j] + 1) % 2);
}
for (int m = 0; m < count1 + count2; m++) {
if (pro[m] > 0)
ret = (byte) ((by[m]) ^ (ret));
}
return ret;
}
轮密钥加是将128位轮密钥Ki同状态矩阵中的数据进行逐位异或操作,如下图所示。其中,密钥Ki中每个字W[4i],W[4i+1],W[4i+2],W[4i+3]为32位比特字,包含4个字节。轮密钥加过程可以看成是字逐位异或的结果,也可以看成字节级别或者位级别的操作。
public byte[][] add(byte sub[][], byte[][] roundkey) {
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++) {
sub[i][j] = (byte) (sub[i][j] ^ roundkey[i][j]);
}
return sub;
}
AES首先将初始密钥输入到一个4*4的状态矩阵中,这个4*4矩阵的每一列的4个字节组成一个字,矩阵4列的4个字依次命名为W[0]、W[1]、W[2]和W[3],它们构成一个以字为单位的数组W.接着,对W数组扩充40个新列,构成总共44列的扩展密钥数组。新列以如下的递归方式产生:
1.如果i不是4的倍数,那么第i列由如下等式确定:
W[i]=W[i-4]⨁W[i-1]
2.如果i是4的倍数,那么第i列由如下等式确定:
W[i]=W[i-4]⨁T(W[i-1])
其中,T是一个有点复杂的函数.函数T由3部分组成:字循环、字节代换和轮常量异或,这3部分的作用分别如下。
a.字循环:将1个字中的4个字节循环左移1个字节。即将输入字[b0, b1, b2, b3]变换成[b1,b2,b3,b0]。
b.字节代换:对字循环的结果使用S盒进行字节代换。
c.轮常量异或:将前两步的结果同轮常量Rcon[j]进行异或,其中j表示轮数。
轮常量Rcon[j]是一个字,其值见下表。
■图5 R值示意图
// 密钥扩展
public byte[][][] key(byte[][] okey) {
byte[][][] retarray = new byte[11][4][4];// 对W数组扩充40个新列,构成总共44列的扩展密钥数组
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++) {
retarray[0][j][i] = okey[i][j];
}
for (int i = 1; i < 11; i++) {
retarray[i] = tkey(retarray[i - 1], r[i]);
}
return retarray;
}
// 密钥扩展中所用函数
public byte[][] tkey(byte[][] okey, int ri) {
byte[][] temp = new byte[4][4];
byte col, row;
col = (byte) (okey[1][3] & 0xf);
row = (byte) ((okey[1][3] >> 4) & 0xf);
temp[0][0] = (byte) (ri ^ sbox[row][col] ^ okey[0][0]);
col = (byte) (okey[2][3] & 0xf);
row = (byte) ((okey[2][3] >> 4) & 0xf);
temp[1][0] = (byte) (sbox[row][col] ^ okey[1][0]);
col = (byte) (okey[3][3] & 0xf);
row = (byte) ((okey[3][3] >> 4) & 0xf);
temp[2][0] = (byte) (sbox[row][col] ^ okey[2][0]);
col = (byte) (okey[0][3] & 0xf);
row = (byte) ((okey[0][3] >> 4) & 0xf);
temp[3][0] = (byte) (sbox[row][col] ^ okey[3][0]);
for (int i = 1; i < 4; i++) {
temp[0][i] = (byte) (temp[0][i - 1] ^ okey[0][i]);
temp[1][i] = (byte) (temp[1][i - 1] ^ okey[1][i]);
temp[2][i] = (byte) (temp[2][i - 1] ^ okey[2][i]);
temp[3][i] = (byte) (temp[3][i - 1] ^ okey[3][i]);
}
return temp;
}
AES的逆行移位与行移位相反,是一个简单的右循环移位操作。当密钥长度为128比特时,状态矩阵的第0行右移0字节,第1行右移1字节,第2行右移2字节,第3行右移3字节。
//逆行移位
public byte[][] shift(byte[][] sub, int mode) {
byte temp;
temp = sub[3][0];
sub[3][0] = sub[3][1];
sub[3][1] = sub[3][2];
sub[3][2] = sub[3][3];
sub[3][3] = temp;
temp = sub[2][0];
sub[2][0] = sub[2][2];
sub[2][2] = temp;
temp = sub[2][1];
sub[2][1] = sub[2][3];
sub[2][3] = temp;
temp = sub[1][0];
sub[1][0] = sub[1][3];
sub[1][3] = sub[1][2];
sub[1][2] = sub[1][1];
sub[1][1] = temp;
return sub;
}
AES的逆字节代替与字节字节代替类似,逆字节代替基于逆s盒。
//逆字节代替
public byte[][] subbyte(byte[][] sub, int r) {
byte row, col;
byte[][] temp = new byte[4][4];
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++) {
col = (byte) (sub[i][j] & 0xf);
row = (byte) ((sub[i][j] >> 4) & 0xf);
temp[i][j] = rsbox[row][col];
}
return temp;
}
逆列混合变换也是通过矩阵相乘来实现的,与固定的矩阵相乘,得到逆混淆后的状态矩阵。
//逆列混合
public byte[][] mix(byte[][] sub, int mode) {
byte count = 0;
byte[][] temp = new byte[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
while (count < 4) {
temp[i][j] = (byte) (temp[i][j] ^ mu(rmut[i][count], sub[count][j]));
count++;
}
count = 0;
}
}
return temp;
}
[1] 何林波 面向对象程序设计[M] 西安:西安电子科技大学出版社,2016.8
[2] 张仕斌. 应用密码学[M].西安:西安电子科技大学出版社,2017.1
[3] 张金全.信息安全数学基础[M]. 西安:西安电子科技大学出版社, 2015.12