例如,AES-128算法加密后的密文的长度是 16字节的整数倍.
若明文长度小于16字节,则密文长度为16字节;
若明文长度等于16字节,则密文长度为32字节.
如果采用 AES-256, 则密钥长度必须是 256位.
MD5 哈希算法的输出是128位
SHA-256 哈希算法的输出是256位
#include <iostream>#include <string>using namespace std;#include <botan/botan.h>using namespace Botan;string cryptoAES128(string input,string passphrase,Cipher_Dir opt);string cryptoAES256(string input,string passphrase,Cipher_Dir opt);int main(){ char src[800]="*"; string input; string key="zhankunlin"; string output; const char *chars=NULL; int length=0; for(int i=strlen(src); i<sizeof(src)-1; i++) { if( i%10 == 0) src[i]=0; else src[i]='A'+i%26; } string x(src,sizeof(src)); input=x; cout<<"-------- 测试 AES-128 加密 -----"<<endl; cout<<"[明文]"<<endl<<input<<endl; output = cryptoAES128(input, key, ENCRYPTION);//加密 chars = output.data(); length = output.size(); cout<<"[密文]"<<endl; for(int i=0; i<length; i++) printf("%*.*X ",-2,2,chars[i]); cout<<endl; cout<<"密文大小: "<<length<<endl;//16的倍数 //模拟C/S结构的发送端和接收端 //发送端构造报文:报文前4个字节是报文长度,为明文;后面跟上密文. int msgLen=length+4; char msgLenChars[4]={}; char *message=new char[msgLen]; memset(message,0,msgLen); sprintf(msgLenChars,"%*.*d",-4,4,msgLen); memmove(message,msgLenChars,4); memmove(message+4,chars,length);//密文 //发送 message //接收端接收 memmove(msgLenChars,message,4); sscanf(msgLenChars,"%d",&msgLen); char *message2=new char[msgLen-4];//密文 memset(message2,0,msgLen-4); memmove(message2,message+4,msgLen-4); string str(message2,msgLen-4);//密文 output=str; output = cryptoAES128(output, key, DECRYPTION);//解密 if(output =="") cout<<"DECRYPTION failed"<<endl; cout<<"[明文]"<<endl<<output<<endl; cout<<"--------------------------------"<<endl; cout<<"-------- 测试 AES-256 加密 -----"<<endl; cout<<"[明文]"<<endl<<input<<endl; output = cryptoAES256(input, key, ENCRYPTION);//加密 chars = output.data(); length = output.size(); cout<<"[密文]"<<endl; for(int i=0; i<length; i++) printf("%*.*X ",-2,2,chars[i]); cout<<endl; cout<<"密文大小: "<<length<<endl;//32的倍数 output = cryptoAES256(output, key, DECRYPTION);//解密 cout<<"[明文]"<<endl<<output<<endl; cout<<"--------------------------------"<<endl; return 0;}//// Parameters/// string input 输入字节串/// string passphrase 用于生成128位密钥的字符串,本函数使用MD5生成128位长度的密钥/// Cipher_Dir opt 加密或解密操作/// ENCRYPTION 加密/// DECRYPTION 解密/// @return 返回操作后的字节串. 若output等于空串,表示解密或者解密失败.//string cryptoAES128(string input,string passphrase,Cipher_Dir opt) { HashFunction* hash = get_hash("MD5"); //MD5算法可以将任意长度的字节串转换为128位长度的字节串 SymmetricKey key = hash->process(passphrase); //产生128位的字节串作为密钥 SecureVector<byte> raw_iv = hash->process('0'+ passphrase); //字符串相加,然后对结果做MD5,生成128位的字节串 InitializationVector iv(raw_iv, 16); //初始化向量 //AES-128是算法名称,分块大小是128bit; CBC是算法模式. //AES算法密钥和分块大小可以是128,192,256位. //AES算法模式还包括: ECB,CFB,OFB,CTR等. Pipe pipe(get_cipher("AES-128/CBC", key, iv, opt)); //Pipe pipe(get_cipher("AES-128/CBC", key, opt)); try{ pipe.process_msg(input); //encryption or decryption. } catch(Botan::Decoding_Error &e) { //解密失败,抛出一个Botan::Decoding_Error类型的异常 cout<< e.what() <<endl; string output=""; return output; } string output=pipe.read_all_as_string(); return output;}//// Parameters/// string input 输入字节串/// string passphrase 用于生成256位密钥的字符串,本函数使用SHA-256生成256位长度的密钥/// Cipher_Dir opt 加密或解密操作/// ENCRYPTION 加密/// DECRYPTION 解密/// @return 返回操作后的字节串. 若output等于空串,表示解密或者解密失败.//string cryptoAES256(string input,string passphrase,Cipher_Dir opt) { HashFunction* hash = get_hash("SHA-256"); //SHA256算法可以将任意长度的字节串转换为256位长度的字节串 SymmetricKey key = hash->process(passphrase); //产生256位的字节串作为密钥 SecureVector<byte> raw_iv = hash->process('0'+ passphrase); InitializationVector iv(raw_iv, 16); //初始化向量,可能会抛出异常 Botan::Invalid_IV_Length //AES-256是算法名称,分块大小是256bit; CBC是算法模式. //AES算法密钥和分块大小可以是128,192,256位. //AES算法模式还包括: ECB,CFB,OFB,CTR等. Pipe pipe(get_cipher("AES-256/CBC", key, iv, opt)); try{ pipe.process_msg(input); //encryption or decryption. } catch(Botan::Decoding_Error &e) { cout<< e.what() <<endl; string output=""; return output; } string output=pipe.read_all_as_string(); return output;}