aes加密解密 crypto实现
?? 因为课程需要,我们要做一个aes的加密解密的小程序,其中核心部分我选择了crypto,但是这个的api又少又难懂,不过还是勉强写完了,
?? 其中包括了cbc,ecb两种连接方式的实现,支持128,192,256位密钥,明文长度不限,填充采用的是标准的(pkcs#5标准)如果明文最后一部分不满16个字节,缺4个字节,那么我在最后4个字节将会填入04,04,04,04,所以我的明文最后的数字范围从(1-16),这个特性将会影响我加密出来的最终结果,这时要特别注意的,
??
代码如下
?
#include <iostream>using namespace std; #include <aes.h>#include <modes.h>#include <string>#include <fstream>using namespace std;using namespace CryptoPP;#pragma comment( lib, "cryptlib.lib" )void AESBasicEncrypt(string input,string key,string output);void AESBasicDecrypt(string input,string key,string output);void AESCBCEncrypt(string input,string key,string iv,string output);void AESCBCDecrypt(string input,string key,string iv,string output);void XorCharArray(unsigned char *a,unsigned char * b,int length);int main(int argc,char *argv[]){ if(argc<2){ cout<< "the parameters has some error"<<endl; system("pause"); return 1; } //AES中使用的固定参数是以类AES中定义的enum数据类型出现的,而不是成员函数或变量 //因此需要用::符号来索引 string aes="AES"; string ECB="ECB"; string InvAES="InvAES"; string CBC="CBC"; string InvCBC="InvCBC"; string InvECB="InvECB"; cout << "AES Parameters: " << endl; cout << "Algorithm name : " << AES::StaticAlgorithmName() << endl; cout << "Algorithm Type : " << argv[1] << endl; if((argv[1]==aes||argv[1]==ECB)&&argc>=5){ cout << "Algorithm InputText : " << argv[2] << endl; cout << "Algorithm InputKey : " << argv[3] << endl; cout << "Algorithm OutputText : " << argv[4] << endl; cout << "Block size : " << AES::BLOCKSIZE * 8 << endl; AESBasicEncrypt(argv[2],argv[3],argv[4]); system("pause"); return 0; } if(argv[1]==CBC&&argc>=6){ cout << "Algorithm InputText : " << argv[2] << endl; cout << "Algorithm InputKey : " << argv[3] << endl; cout << "Algorithm IV : " << argv[4] << endl; cout << "Algorithm OutputText : " << argv[5] << endl; cout << "Block size : " << AES::BLOCKSIZE * 8 << endl; AESCBCEncrypt(argv[2],argv[3],argv[4],argv[5]); system("pause"); return 0; } if(argv[1]==InvCBC&&argc>=6){ cout << "Algorithm InputText : " << argv[2] << endl; cout << "Algorithm InputKey : " << argv[3] << endl; cout << "Algorithm IV : " << argv[4] << endl; cout << "Algorithm OutputText : " << argv[5] << endl; cout << "Block size : " << AES::BLOCKSIZE * 8 << endl; AESCBCDecrypt(argv[2],argv[3],argv[4],argv[5]); system("pause"); return 0; } if((argv[1]==InvAES||argv[1]==InvECB)&&argc>=5){ cout << "Algorithm InputText : " << argv[2] << endl; cout << "Algorithm InputKey : " << argv[3] << endl; cout << "Algorithm OutputText : " << argv[4] << endl; cout << "Block size : " << AES::BLOCKSIZE * 8 << endl; AESBasicDecrypt(argv[2],argv[3],argv[4]); system("pause"); return 0; } cout<< "the parameters has some error"<<endl; system("pause"); return 0;}void AESBasicEncrypt(string input,string key,string output){ ifstream inputTextF; ifstream inputKeyF; ofstream outputF(output.c_str(),ofstream::binary); inputTextF.open(input.c_str(),ifstream::binary); AESEncryption aesEncryptor; char aesKey[32]={0}; unsigned char aesKey2[32]={0}; unsigned char aesText2[16]={0}; char inputT[16]={0}; unsigned char outBlock[AES::BLOCKSIZE]={0}; unsigned char xorBlock[AES::BLOCKSIZE]; memset( xorBlock, 0, AES::BLOCKSIZE ); if(!inputTextF){ cout<< "the "+input+" not found or error"<<endl; return ; } inputKeyF.open(key.c_str(),ifstream::binary); if(!inputKeyF){ cout<< "the "+key+" not found or error"<<endl; return ; } inputKeyF.read(aesKey,32); int end_pos,endNum=0; end_pos = inputKeyF.gcount(); memcpy(aesKey2,aesKey,end_pos); aesEncryptor.SetKey(aesKey2, end_pos ); cout << "key length : " << end_pos * 8 << endl; cout << "output encryption Text : " << endl; while(!inputTextF.eof()) { memset( inputT, 0, AES::BLOCKSIZE ); inputTextF.read(inputT,16); endNum=inputTextF.gcount(); if(endNum<16){ for(int i=endNum;i<16;i++){ inputT[i]=16-endNum; } } memcpy(aesText2,inputT,16); aesEncryptor.ProcessAndXorBlock( aesText2, xorBlock, outBlock ); for( int i=0; i<16; i++ ) { outputF<<outBlock[i]; cout << hex << (int)outBlock[i] << " "; } outputF.flush(); } inputTextF.close(); inputTextF.clear(); inputKeyF.close(); inputKeyF.clear(); outputF.close(); outputF.clear(); cout << endl;}void AESCBCEncrypt(string input,string key,string iv,string output){ ifstream inputTextF; ifstream inputKeyF; ifstream ivF; ofstream outputF(output.c_str(),ofstream::binary); AESEncryption aesEncryptor; char aesKey[32]={0}; unsigned char aesKey2[32]={0}; char inputT[16]={0}; unsigned char aesText2[16]={0}; unsigned char outBlock[AES::BLOCKSIZE]={0}; char ivArray[16]={0}; unsigned char ivArrayU[16]={0}; unsigned char xorBlock[AES::BLOCKSIZE]; int end_pos=0,endNum=0; memset( xorBlock, 0, AES::BLOCKSIZE ); inputKeyF.open(key.c_str(),ifstream::binary); if(!inputKeyF){ cout<< "the "+key+" not found or error"<<endl; return ; } inputKeyF.read(aesKey,32); end_pos = inputKeyF.gcount(); memcpy(aesKey2,aesKey,end_pos); aesEncryptor.SetKey(aesKey2, end_pos ); cout << " key length : " << end_pos * 8 << endl; ivF.open(iv.c_str(),ifstream::binary); if(!ivF){ cout<< "the "+iv+" not found or error"<<endl; return ; } ivF.read(ivArray,16); memcpy(ivArrayU,ivArray,16); ivF.close(); inputTextF.open(input.c_str(),ifstream::binary); if(!inputTextF){ cout<< "the "+input+" not found or error"<<endl; return ; } cout << "output encryption Text : " << endl; while(!inputTextF.eof()) { memset( inputT, 0, AES::BLOCKSIZE ); inputTextF.read(inputT,16); endNum=inputTextF.gcount(); if(endNum<16){ for(int i=endNum;i<16;i++){ inputT[i]=16-endNum; } } memcpy(aesText2,inputT,16); XorCharArray(aesText2,ivArrayU,16); aesEncryptor.ProcessAndXorBlock( aesText2, xorBlock, outBlock ); memcpy(ivArrayU,outBlock,16); for( int i=0; i<16; i++ ) { outputF<<outBlock[i]; cout << hex << (int)outBlock[i] << " "; } outputF.flush(); } inputTextF.close(); inputTextF.clear(); inputKeyF.close(); inputKeyF.clear(); outputF.close(); outputF.clear(); cout << endl;}void AESCBCDecrypt(string input,string key,string iv,string output){ ifstream inputTextF; ifstream inputKeyF; ifstream ivF; ofstream outputF(output.c_str(),ofstream::binary); inputTextF.open(input.c_str(),ifstream::binary); AESDecryption aesDecryptor; char aesKey[32]={0}; unsigned char aesKey2[32]={0}; unsigned char aesText2[16]={0}; char inputT[16]={0}; unsigned char outBlock[AES::BLOCKSIZE]={0}; char ivArray[16]={0}; unsigned char ivArrayU[16]={0}; unsigned char xorBlock[AES::BLOCKSIZE]; memset( xorBlock, 0, AES::BLOCKSIZE ); if(!inputTextF){ cout<< "the "+input+" not found or error"<<endl; return ; } inputKeyF.open(key.c_str(),ifstream::binary); if(!inputKeyF){ cout<< "the "+key+" not found or error"<<endl; return ; } inputKeyF.read(aesKey,32); int end_pos,endNum; end_pos = inputKeyF.gcount(); memcpy(aesKey2,aesKey,end_pos); aesDecryptor.SetKey(aesKey2, end_pos ); //设定密钥 cout << " key length : " << end_pos * 8 << endl; ivF.open(iv.c_str(),ifstream::binary); if(!ivF){ cout<< "the "+iv+" not found or error"<<endl; return ; } ivF.read(ivArray,16); memcpy(ivArrayU,ivArray,16); ivF.close(); memset( inputT, 0, AES::BLOCKSIZE ); cout << "output Decryption Text : " << endl; while(inputTextF.peek()!=EOF) { inputTextF.read(inputT,16); endNum=16; memcpy(aesText2,inputT,16); aesDecryptor.ProcessAndXorBlock( aesText2, xorBlock, outBlock ); XorCharArray(outBlock,ivArrayU,16); //memcpy(xorBlock,outBlock,16); memcpy(ivArrayU,aesText2,16); if(inputTextF.peek()==EOF){ endNum=16-outBlock[15]; } for( int i=0; i<endNum; i++ ) { outputF<<outBlock[i]; cout << hex << (int)outBlock[i] << " "; } cout<<endl; outputF.flush(); memset( inputT, 0, AES::BLOCKSIZE ); } inputTextF.close(); inputTextF.clear(); inputKeyF.close(); inputKeyF.clear(); outputF.close(); outputF.clear(); cout << endl;}void AESBasicDecrypt(string input,string key,string output){ ifstream inputTextF; ifstream inputKeyF; ofstream outputF(output.c_str(),ofstream::binary); inputTextF.open(input.c_str(),ifstream::binary); AESDecryption aesDecryptor; char aesKey[32]={0}; unsigned char aesKey2[32]={0}; unsigned char aesText2[16]={0}; char inputT[16]={0}; unsigned char outBlock[AES::BLOCKSIZE]={0}; unsigned char xorBlock[AES::BLOCKSIZE]; memset( xorBlock, 0, AES::BLOCKSIZE ); if(!inputTextF){ cout<< "the "+input+" not found or error"<<endl; return ; } inputKeyF.open(key.c_str(),ifstream::binary); if(!inputKeyF){ cout<< "the "+key+" not found or error"<<endl; return ; } inputKeyF.read(aesKey,32); int end_pos,endNum; end_pos = inputKeyF.gcount(); memcpy(aesKey2,aesKey,end_pos); aesDecryptor.SetKey(aesKey2, end_pos ); //设定加密密钥 cout << " key length : " << end_pos * 8 << endl; memset( inputT, 0, AES::BLOCKSIZE ); cout << "output Decryption Text : " << endl; while(inputTextF.peek()!=EOF) { inputTextF.read(inputT,16); endNum=16; memcpy(aesText2,inputT,16); aesDecryptor.ProcessAndXorBlock( aesText2, xorBlock, outBlock ); //加密 if(inputTextF.peek()==EOF){ endNum=16-outBlock[15]; } for( int i=0; i<endNum; i++ ) { outputF<<outBlock[i]; cout << hex << (int)outBlock[i] << " "; } cout<<endl; outputF.flush(); memset( inputT, 0, AES::BLOCKSIZE ); } inputTextF.close(); inputTextF.clear(); inputKeyF.close(); inputKeyF.clear(); outputF.close(); outputF.clear(); cout << endl;}void XorCharArray(unsigned char *a,unsigned char * b,int length){ for(int i=0;i<length;i++){ a[i]=a[i]^b[i]; }}?
?代码质量很低,大家随便看看,此外参考了网上一些例子,用法如下
AESCipher.exe CBC ice.txt KeyFile.dat iv.dat outputCBC.dat AESCipher.exe InvCBC outputCBC.dat KeyFile.dat iv.dat outputCBCP.dat AESCipher.exe AES ice.txt KeyFile.dat outputAES.datAESCipher.exe InvAES outputAES.dat KeyFile.dat outputAESP.datAESCipher.exe ECB ice.txt KeyFile.dat outputECB.datAESCipher.exe InvECB outputECB.dat KeyFile.dat outputECBP.dat
?
?ice.txt是原文,keyFile.dat是密钥,outputXXX.dat是密文,ouputXXXP.dat是解密后的原文,源代码附件AES.rar里面有,其中的cryptlib是我利用vs2010生成的crpyto的lib,还有个测试打包的,大家都可以拿去看看