第一篇:今年“5.17”主题确定:信息通信技术与改善道路安全
今年“5.17”主题确定:信息通信技术与改善道路安全
记者从国际电信联盟新闻处和工信部国际合作司获悉,2013年世界电信和信息社会日的庆祝主题已经确定为“信息通信技术与改善道路安全(ICTs and improving road safety)”。
自1969年起,每年5月17日庆祝的“世界电信日”,既是国际电联于1865年成立日,也是同年签署第一份《国际电报公约》的纪念日。2006年3月,就信息社会世界峰会提出的建议,联大通过决议将每年的5月17日同时定为“世界信息社会日”。2006年11月召开的国际电联全权代表大会作出决定,将“双节”合并。自2007年开始,每年的5月17日正式成为世界电信和信息社会日。文章来源:移动通信http://
第二篇:AES-CMAC实验报告 -信息与通信安全
课程名称:姓
名:选择课题:系:专
业:学
号:指导教师:
本科实验报告
信息与通信安全
C/C++实现加解密算法及其应用(实验一)
信电系 信息与通信工程
****年**月**日
目录
1.实验内容与要求.......................................................................................................................3 2.实验原理....................................................................................................................................3
2.1 AES原理..........................................................................................................................3
2.1.1 AES总体结构.......................................................................................................3 2.1.2 AES详细结构.......................................................................................................4 1.1 2.CMAC原理................................................................................................................7
实验环境...........................................................................................................................9
4. 代码实现...............................................................................................................................9
4.1字节代替变换.................................................................................................................9 4.2 行移位变换..................................................................................................................11 4.3列混淆变换...................................................................................................................14 4.4 轮密钥加......................................................................................................................17 4.5 AES的加密与解密的实现............................................................................................22 4.6 CMAC代码实现............................................................................................................23 5.思考题...................................................................................................................................27 6.心得体会...............................................................................................................................27 附录(完整程序).....................................................................................................................28
1.实验内容与要求
(1).复习AES原理。
(2).用C/C++编写AES算法并调试通过。(3).复习CMAC原理。
(4).在实现AES基础上,用C/C++编写CMAC算法并调试通过。(5).回答下列思考题。
AES解密算法和AES的逆算法之间有什么不同? CMAC与HMAC相比,有什么优点?
2.实验原理
2.1 AES原理 2.1.1 AES总体结构
下图展示了AES加密过程的总体结构。明文分组长度为128位即16字节密钥长度可以为16,24或32字节(在本次设计中选择16字节)。
加密和解密算法是输入是一个128位的分组。在FIPS PUB 197中,这个分组被描述为4*4的字节方阵。这个分组被复制到state数组,饼子啊加密或解密的各个阶段被修改。同样,密钥也被描述为字节的方阵,并被扩展为44字的密钥字序列。
密码由N轮组成,其中轮数依赖于密钥长度,16字节密钥是10轮,前N-1轮由4个不同的变换组成:字节代替,行位移,列混淆,轮密钥加。最后一轮包含三个变换,而在第一轮的前面有一个起始的单变换(轮密钥加),可视为第0轮。每一个变换输入一个活多个4*4的矩阵,并输出一个4*4的矩阵,最后一轮输出为密文。同样,密钥扩展函数为N+1轮密钥,它们是互不相同的4*4矩阵。每一个轮密钥作为每轮的轮密钥加变换的一种输入。
2.1.2 AES详细结构
1)
AES算法未使用Feisel结构,而是在每一轮都使用代替和混淆将整个数据分组作为一个单一的矩阵处理。
2)输入的密钥被扩展为44个32位字所组成的数组w[i],每轮由四个不同的字作为该轮的轮密钥。3)由四个不同的阶段组成,包括一个置换和三个代替。字节代替:
用一个S盒完成分组的字节到字节的代替。行位移:
一个简单的置换。列混淆:
利用GF(2^8)上的算术特性的一个代替。轮密钥加:
当前分组和扩展秘钥的一部分进行按位异或。
(一)字节代替变换
如上图,字节代替变换是一个简单的查表操作。AES定义了一个S盒,它由16*16个字节组成的矩阵,包含了8位所能表示的256个数的一个置换。State中 的每个字节按照如下的方式映射为一个新的字节,把改字节的搞4位作为行值,低四位作为列值,以这些行列值作为索引从S盒的对应位置取出元素作为输出。而其逆向操作则是有对应的逆S盒可进行查表。
(二)行移位变换
如上图,其正向行移位变换中,state的第一行保持不变,把state的第二行循环左移一个字节,state的第三行循环左移两个字节,state的第四行循环左移四个字节。例如:
逆向行移位变换将state中的后三行执行相反方向的一位操作即可。
(三)列混淆变换
如上图,列混淆的正向变换是对每列单独进行操作。每列中的每个字节被映射为一个新值,此值由该列中的4个字通过函数变换得到。这个变换可有下面基于state的矩阵乘法表示:
乘积矩阵中的每个元素军事一行和一列中对应元素的乘积之和。这里的乘法和假发都是定义在GF(2^n)上的。状态中单列的列混淆变换可表示为:
其中一个例子如下:
(四)轮密钥加变换
如上图,在轮密钥加变换中,128位的state按位与128位的轮秘钥XOR。该操作可以视为state的一列中的四个字节与轮秘钥的一个字进行列间的操作,例如:
(五)AES密钥扩展
AES密钥扩展算法的输入值是一个4个字,输出值是一个由44个字组成的移位线性数组。
输入密钥字节被复制到扩展密钥数组的前4个字。然后每次用四个字填充扩展密钥数组余下的部分。在扩展数组中,每一个新增的字w[i]的值依赖于w[i-1]和w[i-4]。在4
个情形中,三个使用了异或。对w数组中下标为4的倍数的的元素采用了更复杂的函数来计算:
(1)字循环的功能时使一个字中的四个字节的循环左移一个字节,即将输入字[B0,B1,B2,B3]变成为[B1,B2,B3,B0].(2)字代替利用S盒对输入字中的每个字节进行字节代替。(3)步骤1和步骤2的结果再与轮常量Rcon[j]相异或。
1.1 CMAC原理
基于密码的消息认证码(CMAC)对于AES,3DES适用,它使用三个密钥:一个密钥长为K,用在密文分组链接的每一步,两个长度为n的密钥,其中k是密钥长度,n为密文分组长度。并且两个n位的密钥可以从加密密钥导出,而不是单独提供。首先,当消息长度是分组长度b的n倍时,我们考虑CMAC的运算情况。对AES,b=128,对于3DES,b=64.这个消息被划分为n组,(M1,M2…,Mn)。算法使用了k比特的加密密钥K和n比特的常数K1。对于AES,密钥长度k为128,192和256比特,对于3DES,密钥长度为112或168比特。CMAC按如下方式计算:
C1E(K,M1)C2E(K,[M2C1])C3E(K,[M3C2])...CnE(K,[MNCn1K1])TMSBTlen(Cn)其中:
T——消息认证码,也称为tag Tlen——T的比特长度
MSBs(X)——比特串X最左边的s位
如果消息不是密文分组长度的整数倍,则最后分组的右边(低有效位)填充一个1和若干个0,使得最后的分组长度为b。除了使用一个不同的n比特密钥K2代替K1外,与前面所述一样进行CMAC运算。
两个n比特的密钥由k比特的加密密钥按如下方式导出:
LE(K,0n)K1LxK2LX2(Lx)x其中乘法(·)是在域GF(2^n)内进行,X和X^2是该域的一次和二次多项式。因此X的二元表示为n-2个0,后跟10,X^2的二元表示为n-3个0,后跟100。对于AES,已获批准的分组长度为X^128 +X^7 +X^2 +X+2.。
当消息长度是分组长度的整数倍:
当消息长度不是分组长度的整数倍:
2.实验环境
装有C_Free 的笔记本
4. 代码实现
首先是实现AES的各个子模块,在验证其正确以后,再进行CMAC的认证算法的实现。
4.1字节代替变换
#include
static unsigned char Sbox[256] =
{ //AES的S盒
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
static unsigned char InvSbox[256] = { // AES的逆S盒
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
//字节代替变换
void Sub_Byte(unsigned char state[4][4]){ int i,j;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
state[i][j]=Sbox[state[i][j]];
} //逆向字节代替
void Inv_Sub_Byte(unsigned char state[4][4]){ int i,j;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
state[i][j]=InvSbox[state[i][j]];
}
int main(){ unsigned char state[4][4]={
{0xea,0x04,0x65,0x85},{0x83,0x45,0x5d,0x96},{0x5c,0x33,0x98,0xb0},{0xf0,0x2d,0xad,0xc5}
};int i,j;//正向替换 Sub_Byte(state);
printf(“正向代替结果:n”);for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
printf(“%x ”,state[i][j]);
printf(“n”);
}
printf(“n”);//反向替换
Inv_Sub_Byte(state);
printf(“反向代替结果:n”);
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
printf(“%x ”,state[i][j]);
printf(“n”);
}
}
其测试结果如下,可见该功能可实现是正确的。
4.2 行移位变换
#include
//行移位
void Row_Shift(unsigned char state[4][4]){ int i;unsigned char temp;
} //第一行保持不变,第二行左移一位
temp=state[1][0];for(i=0;i<3;i++)state[1][i]=state[1][i+1];state[1][3]=temp;
//第三行左移2位 temp=state[2][0];state[2][0]=state[2][2];state[2][2]=temp;
temp=state[2][1];state[2][1]=state[2][3];state[2][3]=temp;
//第四行左移3位
temp=state[3][3];for(i=3;i>0;i--)state[3][i]=state[3][i-1];state[3][0]=temp;
//逆向行移位
void Inv_Row_Shift(unsigned char state[4][4]){ int i;unsigned char temp;
//第一行保持不变,第二行右移一位
temp=state[1][3];for(i=3;i>0;i--)state[1][i]=state[1][i-1];state[1][0]=temp;
//第三行右移二位 temp=state[2][0];state[2][0]=state[2][2];state[2][2]=temp;
temp=state[2][1];state[2][1]=state[2][3];state[2][3]=temp;
//第四行右移三位 temp=state[3][0];for(i=0;i<3;i++)state[3][i]=state[3][i+1];state[3][3]=temp;}
int main(){ int i,j;unsigned char state[4][4]={
{0x87,0xf2,0x4d,0x97},{0xec,0x6e,0x4c,0x90},{0x4a,0xc3,0x46,0xe7},{0x8c,0xd8,0x95,0xa6}
};
Row_Shift(state);printf(“正向行移位变换:n”);for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
printf(“%02x ”,state[i][j]);
printf(“n”);
}
printf(“n”);
Inv_Row_Shift(state);
printf(“反向向行移位变换:n”);
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
printf(“%02x ”,state[i][j]);
printf(“n”);
} } 测试结果如下
通过比较,可知结果正确,因此该子模块实现。
4.3列混淆变换
#include
unsigned char x_time2(unsigned char state)//乘2处理
{
unsigned char temp;
if(state>=0x80)
temp=(state<<1)^0x1b;//判断b7=1?
else
temp=(state<<1);
return temp;}
unsigned char x_time3(unsigned char state)//乘3处理
{
state=state^x_time2(state);
return state;}
unsigned char x_time4(unsigned char state)//乘4处理
{
state=x_time2(x_time2(state));
return state;}
unsigned char x_time8(unsigned char state)//乘8处理14
{
state=x_time2(x_time2(x_time2(state)));
return state;}
unsigned char x_time9(unsigned char state)//乘9处理
{
state=state^x_time8(state);
return state;}
unsigned char x_timeB(unsigned char state)//乘B处理
{
state=state^x_time2(state)^x_time8(state);
return state;}
unsigned char x_timeD(unsigned char state)//乘D处理
{
state=state^x_time4(state)^x_time8(state);
return state;}
unsigned char x_timeE(unsigned char state)//乘E处理
{
state=x_time2(state)^x_time4(state)^x_time8(state);
return state;}
void MixColumns(unsigned char state[4][4]){
int i,j;unsigned char state_1[4][4];
for(i=0;i<4;i++)for(j=0;j<4;j++)
state_1[i][j]=state[i][j];
for(j=0;j<4;j++)
{
state[0][j]=x_time2(state_1[0][j])^x_time3(state_1[1][j])^state_1[2][j]^state_1[3][j];
state[1][j]=state_1[0][j]^x_time2(state_1[1][j])^x_time3(state_1[2][j])^state_1[3][j];
state[2][j]=state_1[0][j]^state_1[1][j]^x_time2(state_1[2][j])^x_time3(state_1[3][j]);
state[3][j]=x_time3(state_1[0][j])^state_1[1][j]^state_1[2][j]^x_time2(state_1[3][j]);} } //逆向列混淆
void Inv_MixColumns(unsigned char state[4][4]){ int i,j;unsigned char state_1[4][4];
for(i=0;i<4;i++)for(j=0;j<4;j++)
state_1[i][j]=state[i][j];
for(j=0;j<4;j++){
state[0][j]=x_timeE(state_1[0][j])^x_timeB(state_1[1][j])^x_timeD(state_1[2][j])^x_time9(state_1[3][j]);
state[1][j]=x_time9(state_1[0][j])^x_timeE(state_1[1][j])^x_timeB(state_1[2][j])^x_timeD(state_1[3][j]);
state[2][j]=x_timeD(state_1[0][j])^x_time9(state_1[1][j])^x_timeE(state_1[2][j])^x_timeB(state_1[3][j]);
state[3][j]=x_timeB(state_1[0][j])^x_timeD(state_1[1][j])^x_time9(state_1[2][j])^x_timeE(state_1[3][j]);} } int main(){ int i,j;unsigned char state[4][4]={
{0x87,0xf2,0x4d,0x97},{0x6e,0x4c,0x90,0xec},{0x46,0xe7,0x4a,0xc3},{0xa6,0x8c,0xd8,0x95}
};
MixColumns(state);
printf(“正向列混淆结果: n”);
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
printf(“%x ”,state[i][j]);
printf(“n”);
}
printf(“n”);
Inv_MixColumns(state);
printf(“逆向列混淆结果: n”);
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
printf(“%x ”,state[i][j]);
printf(“n”);
}
} 其测试结果如下:
通过比较,可知结果正确,因此该子模块实现。
4.4 轮密钥加
#include
{ //AES的S盒
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
//秘钥扩展
void key_Expansion(unsigned char key[16]){ int i,j,k;
unsigned char temp[4];//用于寄存w[i-1]
unsigned char t;
unsigned char RC[10]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36};
unsigned char Rcon[10][4]={{0x01,0x0,0x0,0x0},{0x02,0x0,0x0,0x0},{0x04,0x0,0x0,0x0},{0x08,0x0,0x0,0x0},{0x10,0x0,0x0,0x0},{0x20,0x0,0x0,0x0},{0x40,0x0,0x0,0x0},{0x80,0x0,0x0,0x0},{0x1b,0x0,0x0,0x0},{0x36,0x0,0x0,0x0},};
//轮常量
for(i=0;i<16;i++)//将输入秘钥复制到扩展秘钥数组的前四个字
{
ex_key[i]=key[i];
}
for(i=16;i<176;i+=4)//秘钥扩展
{
for(j=0;j<4;j++)
temp[j]=ex_key[i-4+j];//用于寄存w[i-1]
if(i%16==0)//对于w[i]中下标为的4的倍数要使用函数g来计算
{
//循环左移
t=temp[0];
for(k=0;k<3;k++)
temp[k]=temp[k+1];
temp[3]=t;
//字代替
for(k=0;k<4;k++)
temp[k]=Sbox[temp[k]];
//与轮常量相异或
for(k=0;k<4;k++)
temp[k]=temp[k]^Rcon[i/16-1][k];}
// 得到最后的w[i],w[i]=w[i-1]^w[i-4]
for(k=i;k
ex_key[k]=ex_key[k-16]^temp[k-i];
}
} //第k轮的轮密钥加
void RoundKey(unsigned char state[4][4],int k){ int i,j;
for(i=0;i<16;i++)round_key[k][i]=ex_key[16*k+i];//第k轮的轮密钥生成 for(i=0;i<4;i++)
for(j=0;j<4;j++)
state[i][j]=state[i][j]^round_key[k][4*j+i];
}
int main(){
unsigned char key[16]={0x0f,0x15,0x71,0xc9,0x47,0xd9,0xe8,0x59,0x0c,0xb7,0xad,0xd6,0xaf,0x7f,0x67,0x98};unsigned char state[4][4]={
{0xb9,0x94,0x57,0x75},{0xe4,0x8e,0x16,0x51},{0x47,0x20,0x9a,0x3f},{0xc5,0xd6,0xf5,0x3b}
};int i,j;
key_Expansion(key);
for(i=0;i<11;i++)
{
for(j=0;j<16;j++)round_key[i][j]=ex_key[16*i+j];//第k轮的轮密钥生成}
for(i=0;i<11;i++)
{
printf(“第%d轮密钥:n”,i);
for(j=0;j<16;j++)
{
printf(“%02x ”,round_key[i][j]);
if((j+1)%4==0)
printf(“n”);
}
printf(“n”);
}
RoundKey(state,1);
printf(“第一轮结束后的state输出:n”);
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
printf(“%02x ”,state[i][j]);
printf(“n”);
}
return 0;} 扩展密钥数组如下:
经过比对,可知,密钥扩展是正确的。我又选取了第一轮的轮密钥加:
测试结果如下:
经过比对,可知道轮密钥加的结果是正确的。
4.5 AES的加密与解密的实现
(程序请见附录)参照书上给的例子: Plaintext[16]={ 0x01,0x23,0x45,0x67, 0x89,0xab,0xcd,0xef, 0xfe.0xdc,0xba,0x98, 0x76,0x54,0x32,0x10 } key[16]={ 0x0f,0x15,0x71,0xc9, 0x47,0xd9,0xe8,0x59, 0x0c,0xb7,0xad,0xd6, 0xaf,0x7f,0x67,0x98 };其理论结果为:
测试结果如下,经过比对可知结果正确。
4.6 CMAC代码实现
//先用k=128的加密秘钥key产生两个n位的秘钥key_1,key_2 void k1_k2(unsigned char key[16],unsigned char key_1[16],unsigned char key_2[16]){ unsigned char L[16];unsigned char zero_n[16]={0x00};int i;Encryption(zero_n,key,L);//即L=E(K,0^n)
//计算k1=L*x,其中多项式为x^128+x^7+x^2+x+1
if(L[0]>=0x80)
//判断最高位是否是1,若是,则需要约化,即左移一位后,再异或1000 0111=0x87
{
for(i=0;i<16;i++)
key_1[i]=L[i]<<1;//左移一位
key_1[15]=key_1[15]^0x87;
} else {
for(i=0;i<16;i++)
key_1[i]=L[i]<<1;}
//产生key_2=L*x^2=key_1*x
if(key_1[0]>=0x80){
for(i=0;i<16;i++)
key_2[i]=key_1[i]<<1;//左移一位
key_2[15]=key_2[15]^0x87;
}
} else {
for(i=0;i<16;i++)
key_2[i]=key_1[i]<<1;}
//对消息不是密文分组的整数倍,要在分组最后右边填充1及若干个0 //*last_text是最后一个不完整分组,length是最后一组的长度,out_text是填充后的输出
void fill(unsigned char *last_text,int length, unsigned char out_text[16]){ int i;
for(i=0;i<16;i++){
if(i out_text[i]=last_text[i]; else if(i==length) out_text[i]=0x80; else out_text[i]=0x00; } } void AES_CMAC(unsigned char Mass[],unsigned char key[16],int length, unsigned char mac[]){ int i,j,n,last_l;int flag=0;//用于标记密文分组是否完整 unsigned char M_C1[16]={0x00},M_C2[16], M_C_K[16];//用于存放中间数据 unsigned char key_1[16],key_2[16];//分组密钥 unsigned char last[16],Cn[16]; n=(length+15)/16;//用于确定分几组 last_l=length%16; k1_k2(key,key_1,key_2); if(last_l==0) flag=1;//表明是分组长度b=128的整数倍 if(flag==0) fill(&Mass[16*(n-1)],last_l,last);//对前n-1轮 for(i=0;i for(j=0;j<16;j++) M_C2[j]=M_C1[j]^Mass[16*i+j]; Encryption(M_C2,key,M_C1); } if(flag==1) { for(i=0;i<16;i++) M_C_K[i]=Mass[16*(n-1)+i]^M_C1[i]^key_1[i]; Encryption(M_C_K,key,Cn); } else { for(i=0;i<16;i++) M_C_K[i]=last[i]^M_C1[i]^key_2[i]; Encryption(M_C_K,key,Cn); } for(i=0;i<16;i++)mac[i]=Cn[i];} int main(){ unsigned char key[16],Mass[64],T[16]; int i,j,length; printf(“请输入消息(64byte):n”);//输入消息 for(i=0;i<64;i++) scanf(“%x”,&Mass[i]); printf(“请输入密钥: n”);//输入密钥 for(i=0;i<16;i++) scanf(“%x”,&key[i]); printf(“需要使用的次数repeat=:n”); scanf(“%d”,&repeat); for(i=0;i { printf(“请输入不同的密文分组长度length:n”); scanf(“%d”,&length); printf(“AES-CMAC输出结果: n”);AES_CMAC(Mass,key,length,T);for(i=0;i<16;i++) printf(“%x ”, T[i]);printf(“n”);} } 测试结果如下: 根据查阅的资料,可知测试结果是正确的。且从上述结果可知,对于不同的分组长度,输出结果相差很大。 5.思考题 1.AES解密算法和AES的逆算法之间有什么不同? AES解密算法与其逆算法不同点在于解密算法对密文是先进行轮密钥加(对AES-128而言其扩展密钥是w[40,43])然后开始第一轮的逆向求解,而逆算法时对加密算法的求逆,即将第十轮的算法倒推回去,所以这里有区别。这是由AES特定结构所决定的。 2.CMAC与HMAC相比,有什么优点? CMAC使用分组密码算法,而HMAC使用散列函数。因为HMAC是基于其所应用的hash函数的,若hash函数的结构存在缺陷,则HMAC的安全性就会大大降低。而CMAC的安全性采用的是分组密码算法,其安全性在于密钥的长度。CMAC的长度可以通过Tlen的变化而变化,输出位数更加灵活。 6.心得体会 首先,刚开始由于这方面知识掌握不是很好,在看完书后又查阅了大量资料,包括一些程序。在这样的一个基础上,对整个编程的思路有了一些认识,按照书本上的AES加密顺序,最先做的就是密钥扩展和轮密钥加。这个部分也是难度最大的部分,主要是输入的都是字节大小的,但密钥扩展后要求是以字为单位输出的。刚开始这个方面纠结了很久,最后为了整个程序比较清晰,还是决定全都以字节为单位,经过一定转换来得到相当于字的效果。 在完成密钥扩展且测试正确后,就开始按顺序设计,字节代替,行移位,列混淆。其中3盒和逆S盒是直接从网上下载的,其他的就是按照书上给的公式和流程图来完成,还是比较顺利的。其解密算法和加密算法也是大同小异的,只是在每个函数中修改一下相应的代码即可。在加密和解密算法都写完后,就是写main函数进行测试,刚开始发现结果总是不对,经过较长时间的查错,发现还是错在轮密钥加中数组转置引起的问题。 在AES设计万仇就是设计CMAC。关于这个程序书上涉及的也较少,但算法还是比较简单的,主要涉及产生两个子密钥和对不完整的分组填充。由于书上没有现有的例子可以参考,因此,我是参照其他同学的例子,进行比较,验证结果是正确的。 附录(完整程序) #include static unsigned char key[16];//输入秘钥 static unsigned char ex_key[176];//扩展密钥,其中每四个拼成的就是一个字的秘钥数组 //即w[i]=(ex_key[4*i],ex_key[4*i+1],ex_key[4*i+2],ex_key[4*i+3])static unsigned char round_key[11][16];//轮密钥 static unsigned char Sbox[256] = { //AES的S盒 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; static unsigned char InvSbox[256] = { // AES的逆S盒 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; //乘法处理部分 unsigned char x_time2(unsigned char state)//乘2处理 { unsigned char temp; if(state>=0x80) temp=(state<<1)^0x1b;//判断b7=1? else temp=(state<<1); return temp;} unsigned char x_time3(unsigned char state)//乘3处理 { state=state^x_time2(state); return state;} unsigned char x_time4(unsigned char state)//乘4处理 { state=x_time2(x_time2(state)); return state;} unsigned char x_time8(unsigned char state)//乘8处理 { state=x_time2(x_time2(x_time2(state))); return state;} unsigned char x_time9(unsigned char state)//乘9处理 { state=state^x_time8(state); return state;} unsigned char x_timeB(unsigned char state)//乘B处理 { state=state^x_time2(state)^x_time8(state); return state;} unsigned char x_timeD(unsigned char state)//乘D处理 { state=state^x_time4(state)^x_time8(state); return state;} unsigned char x_timeE(unsigned char state)//乘E处理 { state=x_time2(state)^x_time4(state)^x_time8(state); return state;} //秘钥扩展 void key_Expansion(unsigned char key[16]){ int i,j,k; unsigned char temp[4];//用于寄存w[i-1] unsigned char t; unsigned char RC[10]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36}; unsigned char Rcon[10][4]={{0x01,0x0,0x0,0x0},{0x02,0x0,0x0,0x0},{0x04,0x0,0x0,0x0},{0x08,0x0,0x0,0x0},{0x10,0x0,0x0,0x0},{0x20,0x0,0x0,0x0},{0x40,0x0,0x0,0x0},{0x80,0x0,0x0,0x0},{0x1b,0x0,0x0,0x0},{0x36,0x0,0x0,0x0}, }; //轮常量 for(i=0;i<16;i++)//将输入秘钥复制到扩展秘钥数组的前四个字 { ex_key[i]=key[i]; } for(i=16;i<176;i+=4)//秘钥扩展 { for(j=0;j<4;j++) temp[j]=ex_key[i-4+j];//用于寄存w[i-1] if(i%16==0)//对于w[i]中下标为的4的倍数要使用函数g来计算 { //循环左移 t=temp[0]; for(k=0;k<3;k++) temp[k]=temp[k+1]; temp[3]=t; //字代替 for(k=0;k<4;k++) temp[k]=Sbox[temp[k]]; //与轮常量相异或 for(k=0;k<4;k++) temp[k]=temp[k]^Rcon[i/16-1][k];} // 得到最后的w[i],w[i]=w[i-1]^w[i-4] for(k=i;k ex_key[k]=ex_key[k-16]^temp[k-i]; } } //第k轮的轮密钥加 void RoundKey(unsigned char state[4][4],int k){ int i,j; for(i=0;i<16;i++) round_key[k][i]=ex_key[16*k+i];//第k轮的轮密钥生成 for(i=0;i<4;i++) for(j=0;j<4;j++) state[i][j]=state[i][j]^round_key[k][4*j+i]; } //字节代替变换 void Sub_Byte(unsigned char state[4][4]){ int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++) state[i][j]=Sbox[state[i][j]]; } //行移位 void Row_Shift(unsigned char state[4][4]){ int i;unsigned char temp; //第一行保持不变,第二行左移一位 temp=state[1][0];for(i=0;i<3;i++)state[1][i]=state[1][i+1];state[1][3]=temp; //第三行左移二位 temp=state[2][0];state[2][0]=state[2][2];state[2][2]=temp; temp=state[2][1];state[2][1]=state[2][3];state[2][3]=temp; //第四行左移三位,即右移一位 temp=state[3][3];for(i=3;i>0;i--)state[3][i]=state[3][i-1]; state[3][0]=temp;} //列混淆变换 void MixColumns(unsigned char state[4][4]){ int i,j;unsigned char state_1[4][4]; for(i=0;i<4;i++)for(j=0;j<4;j++) state_1[i][j]=state[i][j]; for(j=0;j<4;j++){ state[0][j]=x_time2(state_1[0][j])^x_time3(state_1[1][j])^state_1[2][j]^state_1[3][j]; state[1][j]=state_1[0][j]^x_time2(state_1[1][j])^x_time3(state_1[2][j])^state_1[3][j]; state[2][j]=state_1[0][j]^state_1[1][j]^x_time2(state_1[2][j])^x_time3(state_1[3][j]); state[3][j]=x_time3(state_1[0][j])^state_1[1][j]^state_1[2][j]^x_time2(state_1[3][j]);} } //前9轮每轮有4个步骤 void Round_4(unsigned char state[4][4], int k){ Sub_Byte(state);Row_Shift(state);MixColumns(state);RoundKey(state,k);} //第10轮有3个步骤 void Round_3(unsigned char state[4][4]){ Sub_Byte(state);Row_Shift(state);RoundKey(state,10);} //加密算法,明文 Plaintext,密文CipherText,密钥 key void Encryption(unsigned char Plaintext[16], unsigned char key[16], unsigned CipherText[16]) char { int i,j;unsigned char state[4][4]; for(i=0;i<4;i++) for(j=0;j<4;j++) state[j][i]=Plaintext[4*i+j]; key_Expansion(key);//密钥扩展 //初始轮秘钥加 RoundKey(state,0);//1~10轮 for(i=1;i<10;i++) Round_4(state,i); Round_3(state); //产生密文 for(i=0;i<4;i++) for(j=0;j<4;j++) CipherText[4*i+j]=state[j][i]; } /*////////////////////////////解密////////////////////////////////*/ //逆向行移位 void Inv_Row_Shift(unsigned char state[4][4]){ int i;unsigned char temp; //第一行保持不变,第二行右移一位 temp=state[1][3];for(i=3;i>0;i--)state[1][i]=state[1][i-1];state[1][0]=temp; //第三行右移2位 temp=state[2][0];state[2][0]=state[2][2];state[2][2]=temp; temp=state[2][1];state[2][1]=state[2][3]; } state[2][3]=temp; //第四行右移三位,即左移1位 temp=state[3][0];for(i=0;i<3;i++)state[3][i]=state[3][i+1];state[3][3]=temp;//逆向字节代替 void Inv_Sub_Byte(unsigned char state[4][4]){ int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++) state[i][j]=InvSbox[state[i][j]]; } //逆向列混淆 void Inv_MixColumns(unsigned char state[4][4]){ int i,j;unsigned char state_1[4][4]; for(i=0;i<4;i++)for(j=0;j<4;j++) state_1[i][j]=state[i][j]; for(j=0;j<4;j++){ state[0][j]=x_timeE(state_1[0][j])^x_timeB(state_1[1][j])^x_timeD(state_1[2][j])^x_time9(state_1[3][j]); state[1][j]=x_time9(state_1[0][j])^x_timeE(state_1[1][j])^x_timeB(state_1[2][j])^x_timeD(state_1[3][j]); state[2][j]=x_timeD(state_1[0][j])^x_time9(state_1[1][j])^x_timeE(state_1[2][j])^x_timeB(state_1[3][j]); state[3][j]=x_timeB(state_1[0][j])^x_timeD(state_1[1][j])^x_time9(state_1[2][j])^x_timeE(state_1[3][j]); } } //前9轮每轮有4个步骤 void Inv_Round_4(unsigned char state[4][4], int k){ Inv_Row_Shift(state);Inv_Sub_Byte(state);RoundKey(state,k);Inv_MixColumns(state);} //第10轮有3个步骤 void Inv_Round_3(unsigned char state[4][4]){ Inv_Row_Shift(state);Inv_Sub_Byte(state);RoundKey(state,0);} //解密算法,明文 Plaintext,密文CipherText,密钥 key void Dencryption(unsigned char CipherText[16], unsigned char key[16], unsigned char Plaintext[16]){ int i,j;unsigned char state[4][4]; for(i=0;i<4;i++) for(j=0;j<4;j++) state[i][j]=CipherText[4*j+i]; key_Expansion(key);//密钥扩展 //初始轮密钥加 RoundKey(state,10); //1~10轮 for(i=9;i>0;i--) Inv_Round_4(state,i);Inv_Round_3(state); //产生明文 for(i=0;i<4;i++) for(j=0;j<4;j++) Plaintext[4*i+j]=state[j][i]; } /*/////////////////////////CMAC////////////////////////////*/ //先用k=128的加密秘钥key产生两个n位的秘钥key_1,key_2 void k1_k2(unsigned char key[16],unsigned char key_1[16],unsigned char key_2[16]){ unsigned char L[16];unsigned char zero_n[16]={0x00};int i;Encryption(zero_n,key,L);//即L=E(K,0^n) //计算k1=L*x,其中多项式为x^128+x^7+x^2+x+1 if(L[0]>=0x80) //判断最高位是否是1,若是,则需要约化,即左移一位后,再异或1000 0111=0x87 { for(i=0;i<16;i++) key_1[i]=L[i]<<1;//左移一位 key_1[15]=key_1[15]^0x87; } else { for(i=0;i<16;i++) key_1[i]=L[i]<<1;} //产生key_2=L*x^2=key_1*x if(key_1[0]>=0x80){ for(i=0;i<16;i++) key_2[i]=key_1[i]<<1;//左移一位 key_2[15]=key_2[15]^0x87; } else { for(i=0;i<16;i++) key_2[i]=key_1[i]<<1;} } //对消息不是密文分组的整数倍,要在分组最后右边填充1及若干个0 //*last_text是最后一个不完整分组,length是最后一组的长度,out_text是填充后的输出 void fill(unsigned char *last_text,int length, unsigned char out_text[16]){ int i; for(i=0;i<16;i++){ if(i out_text[i]=last_text[i]; else if(i==length) out_text[i]=0x80; else out_text[i]=0x00; } } void AES_CMAC(unsigned char Mass[],unsigned char key[16],int length, unsigned char mac[]){ int i,j,n,last_l; int flag=0;//用于标记密文分组是否完整 unsigned char M_C1[16]={0x00},M_C2[16], M_C_K[16];//用于存放中间数据 unsigned char key_1[16],key_2[16];//分组密钥 unsigned char last[16],Cn[16]; n=(length+15)/16;//用于确定分几组 last_l=length%16; k1_k2(key,key_1,key_2); if(last_l==0) flag=1;//表明是分组长度b=128的整数倍 if(flag==0) fill(&Mass[16*(n-1)],last_l,last);//对前n-1轮 for(i=0;i for(j=0;j<16;j++) M_C2[j]=M_C1[j]^Mass[16*i+j]; Encryption(M_C2,key,M_C1); } if(flag==1) { for(i=0;i<16;i++) M_C_K[i]=Mass[16*(n-1)+i]^M_C1[i]^key_1[i]; Encryption(M_C_K,key,Cn); } else { for(i=0;i<16;i++) M_C_K[i]=last[i]^M_C1[i]^key_2[i]; Encryption(M_C_K,key,Cn); } for(i=0;i<16;i++)mac[i]=Cn[i];} /*///////////////////////////主函数//////////////////////*/ int main(){ unsigned char Plaintext_1[16]={0x00};unsigned char Ciphertext[16]={0x00};unsigned char Plaintext_2[16]={0x00};unsigned char Mass[64],T[16]; int i,j,length,repeat;//输入明文 printf(“请输入需要加密的明文 :n”); for(i=0;i<16;i++)scanf(“%x”,&Plaintext_1[i]); //输入密钥 printf(“请输入密钥:n”);for(i=0;i<16;i++)scanf(“%x”,&key[i]); //加密 Encryption(Plaintext_1,key,Ciphertext); printf(“加密后的输出密文:n”); for(i=0;i<16;i++) printf(“%02x ”,Ciphertext[i]); printf(“n”); //解密 Dencryption(Ciphertext,key,Plaintext_2); printf(“解密后的输出明文:n”); for(i=0;i<16;i++) printf(“%02x ”,Plaintext_2[i]); printf(“n”); //CMAC printf(“请输入消息(64byte):n”);//输入消息 for(i=0;i<64;i++) { printf(“%02x ”,Mass[i]); if((i+1)%8==0) printf(“n”); } printf(“需要使用的次数repeat=:n”); scanf(“%d”,&repeat); for(j=0;j { printf(“请输入不同的密文分组长度length:n”); scanf(“%d”,&length); printf(“AES-CMAC输出结果: n”); AES_CMAC(Mass,key,length,T); for(i=0;i<16;i++) printf(“%02x ”, T[i]); printf(“n”); } return 0;} 信息与通信技术系 教工党支部 公开承诺书 为了进一步巩固和拓展“戴党徽、亮身份、作表率,创先争优促发展”活动成果,加强基层党组织的战斗堡垒作用,深入开展创优争先活动,不断提高管理水平,提高教育教学质量,我信息与通信技术系教工党支部庄严承诺: 1、开展创先争优活动,加强党的组织建设。坚持支部成员分工明确,责任到位,实现高度统一的民主集中制原则。坚持党务公开制度,不断强化支部成员的团结协作意识、民主意识、责任意识、大局意识、廉政勤政意识、创新意识和群众意识,充分发挥和体现支部成员的组织能力和开展工作的积极性。 2、加强政治理论学习建立学习型基层党组织。认真钻研党建业务知识,完善学习制度。密切党群、干群联系,营造积极向上、健康和谐的工作环境,加强支部与支部、支部与行政科室的横向联系,共同搭建开展活动的平台,充分调动全体党员的积极性和创造性,增强党组织的凝聚力和向心力。 3、规范组织发展程序,做好党员发展工作。严格发展程序,认真履行手续,确保发展党员质量。把好培养教育关、考察关、审批关。切实加强对入党积极分子的培养、教育,做到培训有计划,培养措施到位。坚持标准、保证质量、改善结构、谨慎发展,认真搞好组织发展工作。 4、充分发挥党支部的战斗堡垒作用,抓好一个党员一面旗帜长效活动,落实党员责任区制度,抓好党员示范性和先进性教育。每位党员制定创先争优目标承诺书。 5、加强师德师风建设,努力提高本支部党员的党性修养和业务能力。树立教师良好形象,发扬奉献精神,爱岗敬业,保证教育教学质量。树立大局意识、发展意识、服务意识、育人意识,做到春风化雨,服务育人。 6、规范管理,强化教师教育教学常规工作的落实,严格执行课程计划。做到支部常规工作制度化、规范化。 7、加强廉政建设,教育全体党员廉洁奉公,自觉抵制不正之风的侵袭。 我党支部将自觉接受上级和全体教师的监督,做好基层各项工作,办人民满意教育。 第五届通信网络和信息安全高层论坛 参会邀请函 尊敬的女士/先生: 在工业和信息化部通信保障局的指导下,由中国通信学会普及与教育工作委员会、人民邮电出版社主办,北京信通传媒有限责任公司承办的“2013通信网络和信息安全高层论坛”将于2013年4月11日在北京鸿翔大厦举办。 论坛将以“协作创新应对安全变革新时代”为主题,针对实名制下的网络安全、云计算公共服务网络安全、基于云的第三方灾难备份、IDC类应用系统安全防护、电信网络的安全防护评测和管理、IPv6网络安全保障体系研究、Web应用安全、移动互联网的安全和挑战等议题展开深入研讨和交流。 联系人: 电话: 邮件: 北京信通传媒有限责任公司 2013年4月6日 网络信息安全与防火墙技术 钟琛 (2012级软件开发(3)20150609) 摘 要:随着计算机网络技术的迅速发展,特别是互联网应用得越来越广泛,网络安全成为了社会关注的焦点问题。由于网络开放的、无控制机构的特点,使其安全得不到保障。社会针对计算机网络安全,提出了许多保护措施,其中防火墙技术的应用相对较为明显,不仅显示了高水平的安全保护,于此同时营造了安全、可靠的运行环境。大部分的黑客入侵事件都是因为没有正确安装防火墙而引起的,所以我们应该高度重视和注意防火墙技术。因此,该文对计算机网络安全进行研究,并且分析防火墙技术的应用。关键字:计算机;网络技术;网络安全;防火墙技术 Abstract:With the rapid development of computer network technology, particularly the Internet, network security has become focused by more and more people.As the network open, uncontrolled body characteristics, its security cannot be guaranteed.Social people put forward a number of safeguards to protect computer network security,the application of firewall technology is relatively obvious, not only shows a high level of security, atthe same time,it also create a safe and secure operating environment.Most of the hacking incident is due to they did not properly install a firewall and cause, so we should attach great importance and attention to firewall technology.Therefore this article aimed to show some study of computer network security research, and analysis the application of firewall technology.Key words: computer;network technology;network security;firework technology 随着计算机网络的飞速发展,人们的工作,学习和生活正在不断地被计算机信息技术改变,人们的工作效率有了很大的提高,但由于计算机网络的多样性、分布不均的终端、互联性和开放性的特点,这种形式在网络和网络中极容易受到黑客,病毒,恶意软件和其他意图不明的行为攻击,因此网络信息的安全性和保密性是一个关键的问题。因此,网络的安全措施应该是一个能够面对全方位不同的威胁,只有这样网络信息的保密性、完整性和可用性才能得到保障。分析计算机网络安全与防火墙技术 计算机网络安全与防火墙技术之间存在密不可分的关系,防火墙技术随着计算机网络的需求发展,网络安全反映计算机网络安全和防火墙技术之间的技术优势。计算机网络安全与防火墙技术的分析如下: 1.1计算机网络安全 安全是计算机网络运行的主要原则,随着现代社会的信息化发展,计算机网络已经得到了推进,但是其在操作过程中依然出现安全威胁,影响计算机网络的安全级别,计算机网络安全威胁包括: 1.1.1 数据威胁 在计算机网络中数据是主体,在运行的过程中数据存在许多漏洞,从而导致计算机网络的安全问题。例如:一个计算机网络节点的数据,比较容易篡改,破坏数据的完整性,攻击者利用数据内容的一部分,窥探内网数据、泄漏数据,利用计算机网络系统漏洞,植入木马、病毒,导致系统数据瘫痪,无法支持计算机网络安全的运行。1.1.2 外力破坏 外力破坏是计算机网络安全运行不可忽视的危险部分,最主要的是人为破坏,如:病毒、木马的攻击等。目前,这种类型对计算机网络的影响比较大,一些网站病毒、邮件病毒等方式的攻击者,对用户的计算机进行攻击、病毒植入时,大多是因为用户操作习惯的不正确,从而使计算机网络系统出现漏洞。例如:用户浏览外部网站很长一段时间,但不能对病毒进行定期处理,攻击者可以很容易地找出用户的浏览习惯,添加此类链接的特性攻击网站,当用户点击该网站时,病毒立即开始攻击客户的计算机。1.1.3 环境威胁 在共享环境中的计算机网络,资源受到威胁。环境是计算机网络操作的基础,用户在访问外部网络时必须经过网络环境,所以是有显著的环境威胁的,当用户访问网络时,该攻击在网络环境中非常强,攻击者通过网络环境设置主要攻击范围,特别是对网络环境内交互的数据包进行攻击,保护内部网络的结构受到损坏,对环境的威胁,必须发挥防火墙技术的全部功能。 2防火墙的基本原理 2.1防火墙的概念 防火墙指的是一个由软件和硬件设备组合而成、在内部网和外部网之间、专用网与公共网之间的界面上构造的保护屏障。它按照规定的安全策略对网络之间进行传输的数据包进行检查,然后决定是否允许该通信,将内部网对外部网屏蔽信息、运行状况和结构,从而使内部网络达到保护内部网络的信息不被外部非授权用户访问和过滤不良信息目的。 防火墙本质上是一种隔离控制技术,其核心思想是在网络中不安全的环境,构建一个相对安全的内部网络环境。从逻辑上讲它既是一个解析器又是一个限制器,它要求所有传入和传出的网络数据流必须验证和授权并且将外部网络和内部网络在逻辑上分离出来。 防火墙可以全部是硬件,也可以全部是软件,它也可以是硬件和软件两者。防火墙与内部网络和外部网络(互联网)之间的关系如图1。 图1 2.2 防火墙的作用 2.2.1 “木桶”理论在网络安全的应用 网络安全概念有一个“木桶”理论:一只水桶能装水并不取决于桶有多高,而是取决于高度和最短的那块木板的桶组成。防火墙理论的应用是“木桶”。在一个环境中没有防火墙,网络安全只能体现在许多主机的功能,所有主机都必须共同努力,以实现更高程度的安全性。防火墙可以简化安全管理,网络安全是加强防火墙系统,而不是分布在内部网络中的所有主机上。 2.2.2 内部网络安全性的强化 防火墙可以限制未授权的用户,如防止黑客或者破坏网络的人进入内部网络,不让不安全的脆弱性的服务(如NFS)和没有进行授权的信息或通信进出网络,并抵抗从各个地方和路线来的攻击。 2.2.3 将网络存取和访问进行记录、监控 作为一个单一的网络接入点,所有传入和传出的信息必须通过防火墙,防火墙是非常适合收集系统和网络的使用和误用,并且将记录信息。在防火墙上可以很容易地监控网络安全,并且报警。 2.2.4 限制内部用户访问特殊站点 防火墙来确定合法用户的用户认证。通过事先确定的检查策略,以决定哪些内部用户可以使用该服务,可以访问某些网站。2.2.5 限制暴露用户点,阻止内部攻击 用防火墙将内部网络进行划分,它使网段隔离,以防止网络问题通过整个网络,这限制了本地焦点或敏感网络安全问题的全球网络上传播的影响,同时保护网络从该网络中的其他网络攻击 2.2.6 网络地址转换 防火墙部署为一个NAT逻辑地址,因此防火墙可以使地址空间短缺的问题得到缓解,并当一个组织变革带来的ISP重新编号时消除麻烦。作为一个单一的网络接入点,所有传入和传出的信息必须经过防火 2.2.7 虚拟私人网络 防火墙还支持互联网服务功能的企业网络技术体系VPN。VPN将企业在局域网还是在世界各地的专用子网的地理分布,有机地联系起来,形成一个整体。不仅省去了专用通信线路,而且还提供技术支持,信息共享。3防火墙的类型 在设计中的防火墙,除了安全策略,还要确定防火墙类型和拓扑结构。根据所用不同的防火墙技术,我们可以分为四个基本类型:包过滤型、网络地址转换--NAT,代理服务器型和监视器类型。3.1包过滤型 包过滤防火墙产品是基于其技术网络中的子传输技术在初始产品。网络上的数据传输是以“包”为单位的,数据被划分成大小相当的包,每个包将包含特定信息,如地址数据源,目的地址,TCP / UDP源端口和目的端口等。防火墙通过读取地址信息来确定“包”是否从受信任的安全站点,如果发现来自不安全站点的数据包,防火墙将这些数据阻挡在外部。3.2网络地址转化--NAT 网络地址转换是把IP地址转换成临时的、外部的,注册的D类地址的标准方法。它允许拥有私有IP地址的内网访问互联网。这也意味着,用户不能获得每个设备的IP地址注册为网络。当内网通过安全的网卡访问外网时,会有一个映射记录产生。系统将外出的源地址和源端口映射为一个伪装的地址和端口,所以地址和端口通过不安全网络卡和外部网络连接的伪装,所以它隐藏了真正的内部网络地址。3.2代理(Proxy)型 代理防火墙同样也可以被称为代理服务器,它比包过滤产品更加安全,并已开始开发应用程序层。在客户端和服务器之间的代理服务器位于,完全阻断两者的数据交换。从客户端的角度来看,代理服务器充当真实服务器,从服务器运行时,代理服务器是一个真正的客户端。当客户端需要使用服务器上的数据,第一数据请求发送到代理服务器,然后代理服务器获得数据到服务器响应请求,然后由代理服务器将数据发送给客户端。由于在外部系统与内部服务器之间没有直接的数据联通,这对企业网络系统来说,外部的恶意破坏不足以伤害到。3.4监测型 监控防火墙是新一代的产品,最初的防火墙定义实际上已经被这一技术超越了。防火墙可以监视每一层活性,实时监控数据,在监视器防火墙上的数据的分析的基础上,可以有效地确定各层的非法侵入。与此同时,这种检测防火墙产品一般还具有分布式探测器,这些探测器放置在节点、各种应用服务器和其它网络之间,不仅可以检测来自网络外部的攻击,同时对从内部恶意破坏也有很强的的预防效果。据权威部门计算,在攻击的网络系统中,从网络中有相当比例的是从内部网络开始的。因此,监测的防火墙不仅超越了防火墙的传统定义,而且在安全性也超越了前两代产品。虽然监测防火墙的安全方面已经超出包过滤和代理防火墙,但由于监测防火墙昂贵的实施技术,而且不易于管理,所以现在在实际使用中的防火墙产品仍然在第二代代理型产品,但在某些方面已经开始使用监控防火墙。基于全面考虑了系统成本和安全技术的成本,用户可以选择性地使用某些技术进行监控。这不仅保证了网络的安全性要求,而且还可以有效地控制总拥有成本的安全系统。4 结束语 防火墙是新型的重要的Internet安全措施,在当前社会得到了充分的认可和广泛的应用,并且由于防火墙不仅仅限于TCP / IP 协议的特点,也让它渐渐地在除了Internet之外其他的领域也有了更好的发展。但是防火墙只是保护网络安全和网络政策和策略中的一部分,所以这并不能解决网络安全中的所有问题。防火墙如果要保护网络安全,那么这和许多因素有关,要想得到一个既高效又通用、安全的防火墙,通常要将各种各样的防火墙技术和其它网络安全技术结合在一起,并且配合要有一个可行的组织和管理措施,形成深度有序的安全防御体系。 参考文献 [1]宿洁,袁军鹏.防火墙技术及其进展,计算机工程与应用(期刊论文),2004 [2]马利,梁红杰.计算机网络安全中的防火墙技术应用研究,电脑知识与技术,2014 [3]解静静.网络信息安全与防火墙技术,计算机光盘软件与应用,2014 [4]陈倩.浅析网络安全及防火墙技术在网络安全中的应用,网络安全技术与应用,2014 [5]赵子举.浅谈入侵检测与防火墙技术,电子世界,2014第三篇:信息与通信技术系 教工党支部 公开承诺书
第四篇:通信网络与信息安全论坛邀请函
第五篇:网络信息安全与防火墙技术