【加密/解密】Botan 中的 AES 加密算法实例

AES 算法的密钥和分块大小可以是128,192,256位.
例如,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;
}








  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值