基于AES加密的Windows Socket网络通信实现
2014-03-19闫庚哲
闫庚哲
(哈尔滨理工大学软件学院,哈尔滨150036)
·微机网络与通信·
基于AES加密的Windows Socket网络通信实现
闫庚哲
(哈尔滨理工大学软件学院,哈尔滨150036)
随着互联网技术的飞速发展,网络安全逐渐成为一个潜在的巨大问题。为了保障用户的自身权益,提高用户通信内容的安全性就显得尤为重要。因此,在网络通信的传输中采用AES高级加密方法,可以有效提高信息传输的安全性。以Windows Socket网络通信方式为例,介绍了应用AES加密算法的实现,并给出了C++语言代码。
高级加密标准;网络安全;加密;网络通信;套接字
1 引 言
1.1 AES原理
1.1.1 AES简介
密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法。这个标准用来替代原先的DES[1],已经被多方分析且广为全世界所使用。AES[2-5]算法是美国标准技术研究所(NIST)于2001年11月正式发布的,它是一种分组加密算法,处理的最小单元是一个分组,即把明文或密文分成固定长度的分组,进而进行加密或解密处理。AES的分组大小为128比特,可以支持的密钥长度有128、192、256三种,分别称为AES-128、AES-192、AES-256,其中又以AES-128应用最广[6]。
1.1.2 AES算法
AES算法中较为重要的是多次迭代操作[7],每一次迭代操作包涵字节替换(subbyte)、行移位(shiftrow)、列混合(mixcolumns)和轮密钥混合(addroundkey)等四部分。经过多次迭代变化从而提高信息的加密强度。解密过程则为加密过程的逆运算。
1.2 Socket网络通信原理
1.2.1 Socket简介
Socket(套接字)是建立在传输层协议(主要是TCP和UDP)上的一种套接字规范。Socket具有信息收发速度快、保密性好、占用服务器吞吐量小、易于编程实现等优点[8]。
Socket接口包含Server Socket(服务器端,它是通信的响应方,它监听以及被动接受客户端的连接请求,并对请求进行回复)和Client Socket(客户端,它是通信的请求方,主动与服务器端建立连接)两个组件。常用的Socket网络通信一般采用Client-Server模式,各客户端都和服务器端连接。此通信模式结构简单、编程易实现,但各客户端之间不能直接通信,需通过服务器端转发。
1.2.2 Socket通信原理
socket通常也称作“套接字”[8],用于描述IP地址和端口,是一个通信链句柄。应用程序通常通过“套接字”向网络发出请求或者应答网络请求。服务器使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。客户端使用ClientSocket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时、动态的分配一个1024以上的端口。
2 加密传输介绍
发送方:在本地对明文用私人参数作AES算法加密,调用Winsock的发送处理函数Send()将加密后的内容发送到网络中。
接收方:调用Winsock的接收处理函数Recv()获取网络中的密文信息,在本地对密文用私人参数作AES算法解密。
实现客户服务器之间用socket进行通信,并且明文查看,密文传输的功能。
3 加密传输的C++实现代码
3.1 AES算法的C++实现代码
加密过程和解密过程都是一个周期迭代的过程,以AES-128为例,迭代次数为10次。数据首先和128比特的原始密钥经过addroundkey运算后再进行10轮运算。10轮运算由字节替换(subbyte)、行移位(shiftrow)、列混合(mixcolumns)和轮密钥混合(addroundkey)组成,其中算法定义最后一轮运算不进行列混合操作。
3.1.1 加密的基本C++实现代码
3.1.1.1 字节替换
字节替换运算是一个可逆的非线性字节代换操作,该运算处理的最小单位是一个字节,也就是4×4字节矩阵中的一个元素。对字节的替换操作可以基于一个代换表(又称S盒)。字节替换表由两个独立变换组成:有限域GF(28)中字节的乘法逆运算和有限域GF(2)中的仿射变换[9]。
void AES::SubBytes(unsigned char state[][4]){
for(r=0;r<4;r++)for(c=0;c<4;c++)state[r][c]=Sbox[state[r][c]];}
3.1.1.2 行移位
加密中的行移位将每一行进行循环左移位,即最高位字节移动到最低位字节。具体移位的数目与行的序号有关,第零行不进行移位,第一行循环左移一个字节,第二行循环左移两个字节,第三行循环左移三个字节…。
void AES::ShiftRows(unsigned char state[][4]){
for(r=1;r<4;r++){
for(c=0;c<4;c++)t[c]=state[r][(c+r)%4];
for(c=0;c<4;c++)state[r][c]=t[c];}}
3.1.1.3 列混合
列混合主要以每一列为单位并进行处理,每一列看作一个GF(28)[9]下的4位多项式。利用该多项式和c(x)={03}x^3+{01}x^2+{01}x+{02}进行多项式乘法,乘法结果再进行取模运算,模的值为(X^4+1)。
void AES::MixColumns(unsigned char state[][4]){
for(c=0;c<4;c++){
for(r=0;r<4;r++)t[r]=state[r][c];
for(r=0;r<4;r++)state[r][c]=FFmul(0x02,t[r])^FFmul(0x03,t[(r+1)%4])^FFmul(0x01,t[(r+2)%4])^FFmul(0x01,t[(r+3)% 4]);}}
unsigned char AES::FFmul(unsigned char a,unsigned char b){
bw[0]=b;
for(i=1;i<4;i++){
bw[i]=bw[i-1]<<1;
if(bw[i-1]&0x80)bw[i]^=0x1b;}
for(i=0;i<4;i++)if((a>>i)&0x01)res^=bw[i];
return res;}
3.1.1.4 轮密钥混合
简单来说就是逐字节相加,有限域GF(28)上的加法是模2加法,即异或
void AES::AddRoundKey(unsigned char state[][4],unsigned char k[][4]){
for(c=0;c<4;c++)for(r=0;r<4;r++)state[r][c]^=k[r][c];}
3.1.1.5 密钥扩展
将输入的密钥扩展为11组128位密钥组,其中第0组为输入密钥本身,其后第n组第i列为第n-1组第i列与第n组第i-1列之和(模2加法,1<=i<=3)
void AES::KeyExpansion(unsigned char*key,unsigned char w[][4][4]){
unsigned char rc[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36};
for(r=0;r<4;r++)for(c=0;c<4;c++)w[0][r][c]=key[r+c*4];
for(i=1;i<=10;i++)for(j=0;j<4;j++){
unsigned char t[4];
for(r=0;r<4;r++)t[r]=j?w[i][r][j-1]:w[i-1][r][3];
if(j==0){
unsigned char temp=t[0];
for(r=0;r<3;r++)t[r]=Sbox[t[(r+1)% 4]];
t[3]=Sbox[temp];
t[0]^=rc[i-1];}
for(r=0;r<4;r++)w[i][r][j]=w[i-1][r][j]^t[r];}}
3.1.2 解密的基本C++实现代码
解密算法,基本运算中除了AddRoundKey(轮密钥加)不变外,其余的都需要进行逆变换。即Inv-SubBytes(逆字节替代)、InvShiftRows(逆行移位)、InvMixColumns(逆列混淆)。
void AES::InvSubBytes(unsigned char state[][4]){
for(r=0;r<4;r++)for(c=0;c<4;c++)state[r][c]=InvSbox[state[r][c]];}
void AES::InvShiftRows(unsigned char state[][4]){;
for(r=1;r<4;r++){
for(c=0;c<4;c++)t[c]=state[r][(c-r+4)%4];
for(c=0;c<4;c++)state[r][c]=t[c];}}
void AES::InvMixColumns(unsigned char state[][4]){
for(c=0;c<4;c++){
for(r=0;r<4;r++)t[r]=state[r][c];
for(r=0;r<4;r++)state[r][c]=FFmul(0x0e,t[r])^FFmul(0x0b,t[(r+1)%4])^FFmul(0x0d,t[(r+2)%4])^FFmul(0x09,t[(r+3)% 4]);}}
3.1.3 加密过程的C++实现代码
先将输入的明文按列序组合成4×4矩阵,直接与第0组密钥(即输入的密钥)相加(异或),作为轮加密的输入。然后循环10次进行SubBytes、ShiftRows、MixColumns、AddRoundKey运算,最后恢复原序列。需要注意的是最后一轮并不进行Mix-Columns(列混淆变换)。
unsigned char*AES::Cipher(unsigned char* input){
for(r=0;r<4;r++)for(c=0;c<4;c++)state[r][c]=input[c*4+r];
AddRoundKey(state,w[0]);
for(i=1;i<=10;i++){
SubBytes(state);
ShiftRows(state);
if(i!=10)MixColumns(state);
AddRoundKey(state,w[i]);}
for(r=0;r<4;r++)for(c=0;c<4;c++)input[c*4+r]=state[r][c];
return input;}
3.1.4 解密过程的C++实现代码
unsigned char*AES::InvCipher(unsigned char *input){
for(r=0;r<4;r++)for(c=0;c<4;c++)state[r][c]=input[c*4+r];
AddRoundKey(state,w[10]);
for(i=9;i>=0;i--){
InvShiftRows(state);
InvSubBytes(state);
AddRoundKey(state,w[i]);
if(i)InvMixColumns(state);}
for(r=0;r<4;r++)for(c=0;c<4;c++)input[c*4+r]=state[r][c];
return input;}
3.2 Socket通信的C++实现代码
3.2.1 客户端加密发送的C++实现代码
void__fastcall TForm1::btnclientSendClick(TObject*Sender){
AES aes;//读入密钥文件
FileRead(keyFile,(char*)key,16);//读入明文并加密
while(FileRead(plainFile,(char*)plainText,16))
cipherText=aes.Cipher(plainText,key,16);//发送密文
AnsiString cipher;
cipher=AnsiString((char*)cipherText);
ClientSocket->Socket->SendText(cipher);}
3.2.2 服务器解密接收的C++实现代码
void__fastcall TForm1::btnDecryptClick(TObject*Sender){
AES aes;//读入解密密钥
FileRead(keyFile,(char*)key,16);//读入解密密文
while(FileRead(cipherFile,(char*)cipher-Text,16))
plainText=aes.InvCipher(cipherText,key,16);//接收密文
AnsiStringmemoPlain;
memoPlain=(AnsiString)((char*)plain-Text);
Memo1->Lines->Add(memoPlain);}
4 结束语
随着互联网技术的高速发展,尤其是互联网的应用变得越来越广泛,在带来海量信息的同时,网络的开放性和自由性也产生了私有信息被泄露的可能性,网络信息的安全性变得日益重要起来。对于目前存在的网络安全问题,为了提高信息传输的安全性,该文以Windows Socket网络通信方式为例,采用AES的高级加密方法进行加密传输,可以有效避免信息在传输过程中被别人窃用。
[1]张洁,朱丽娟.DES加密算法分析与实现[J].软件导刊,2007(3):95-97.
[2]Daemen J,Rijmen V.The Design of Rijndael:AES-the Advanced Encryption Standard[M].Berlin:Springer-Verlag,2012.
[3]Kuleuven.A Polynomial Description:The Original Description of Rijndael[EB/OL].ESAT:Kuleuven,2010.http://www.esat.kuleuven.ac.be/rijmen/rijndael/1.net.
[4]何明星,范平志.新一代私钥加密标准AES进展与评述[J].计算机应用研究,2001,18(10):4-6.
[5]吴小博.AES加密算法分析与C++编程实现[J]计算机安全,2007(12):44-46.
[6]单玉峰,潘孟贤.一种新的加密标准AES[J].信息技术,2002(11):32-33.
[7]何明星,范平志.新一代私钥加密标准AES进展与评述[J].计算机应用研究,2001(10):4.
[8]王茂林,贺富强.Socket在局域网通信中的应用[J].舰船电子工程,2006,26(5):93-95.
[9]NIST.Announcing the ADVANCED ENCRYPTION STANDARD(AES)[M].America:Springer-Verlag,2001.
Implement of AES-based Encryption Windows Socket Network Communication
YAN Geng-zhe
(College of Software,Harbin University of Technology,Harbin 150036,China)
With the rapid development of internet technology,network security has become a potentially huge problem.In order to protect the rights and interests of user's own,security of user communication content should be focused on particularly.Therefore,AESAdvanced Encryption method is used in the network communication to effectively improve the security of information transmission.Windows socket network communication is given an example,the application of the AES encryption algorithm is described and the C++language code is shown in this paper.
AES;Network security;Encryption;Network communication;Socket
10.3969/j.issn.1002-2279.2014.03.005
TP393
:B
:1002-2279(2014)03-0014-04
闫庚哲(1993-),男,黑龙江哈尔滨人,本科,主研方向:软件工程。
2013-11-21