【暗号化/復号化】BotanにおけるAES暗号化アルゴリズムの例


AESアルゴリズムの鍵及びブロックサイズは、128192256ビットであるもよい.
例えば、AES-128アルゴリズムの暗号化後の暗号文の長さは、16バイトの整数倍である.
明文の長さが16バイト未満の場合、暗号文の長さは16バイトである.
明文の長いが16バイトに等しいと、暗号文の長いは32バイトとなる.
AES-256を用いる場合、鍵長は256ビットである必要がある.
MD 5ハッシュアルゴリズムの出力は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;
}