Crypto++库在VS 2013中的使用 + 基于操作模式AES加密

一.   下载Crypto++ Library

Crypto++ Library的官方网:http://www.cryptopp.com/

 

二.   建立自己使用的Crypto++ Library

由于从官方网下载的Crypto++库是开源的,只有源文件和几个可以生成lib、dll的工程,以及一个使用的例子工程,因此希望生成自己建的工程能使用的SDK。

 

1.编译链接生成cryptlib.lib

打开cryptest.sln,分别在Debug模式和Release模式下编译链接cryptlib工程,成功后会在cryptopp54\Win32\output\debug和cryptopp54\Win32\output\release下生成cryptlib.lib文件。作者当时用的是Crypto++ 5.62版本。

Build时方法是,右击Solution Explorer中的cryptlib工程,单击build。第一次时它会报错,没关系,按这样再build一次,就可以build成功了。

2.  建立Crypto++ SDK

在C:\Program Files\中新建文件夹,取名“CryptoPP”,里面新建文件夹“include”、“lib”,在“lib”中新建文件夹“debug”、“release”。将Crypto++库中的所有头文件复制到“include”文件夹中,再将上面生成的两个cryptlib.lib分别复制到“debug”和“release”中。


三.  基于模式的AES加解密

1、20/13中新建Win32 Console Application工程,建立空的工程。完成后新建文件main.cpp,里面源码如下:

#include "stdafx.h"
#include <aes.h>
#include <Hex.h>      // StreamTransformationFilter
#include <modes.h>    // CFB_Mode
#include <iostream>   // std:cerr  
#include <sstream>   // std::stringstream  
#include <string>


using namespace std;
using namespace CryptoPP;
#pragma comment( lib, "cryptlib.lib" )

std::string ECB_AESEncryptStr(std::string sKey, const char *plainText)
{
    std::string outstr;
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
      
    AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);  
      
    ECB_Mode_ExternalCipher::Encryption ecbEncryption(aesEncryption);
    StreamTransformationFilter ecbEncryptor(ecbEncryption, new HexEncoder(new StringSink(outstr)));  
    ecbEncryptor.Put((byte *)plainText, strlen(plainText));  
    ecbEncryptor.MessageEnd();  
      
    return outstr;  
}  



std::string ECB_AESDecryptStr(std::string sKey, const char *cipherText)  
{  
    std::string outstr;  
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
    ECB_Mode<AES >::Decryption ecbDecryption((byte *)key, AES::MAX_KEYLENGTH);  
          
    HexDecoder decryptor(new StreamTransformationFilter(ecbDecryption, new StringSink(outstr)));  
    decryptor.Put((byte *)cipherText, strlen(cipherText));  
    decryptor.MessageEnd();  
      
    return outstr;  
}  



std::string CBC_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText)
{
    std::string outstr;
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
    //填iv  
    byte iv[AES::BLOCKSIZE];  
    memset(iv,0x30,AES::BLOCKSIZE); 
sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);
      
    AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);  
      
    CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv);  
      
    StreamTransformationFilter cbcEncryptor(cbcEncryption, new HexEncoder(new StringSink(outstr)));  
    cbcEncryptor.Put((byte *)plainText, strlen(plainText));  
    cbcEncryptor.MessageEnd();  
      
    return outstr;  
}  

std::string CBC_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText)  
{  
    std::string outstr;  
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
    //填iv  
    byte iv[AES::BLOCKSIZE];  
    memset(iv,0x30,AES::BLOCKSIZE);  
sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);


    CBC_Mode<AES >::Decryption cbcDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);  
          
    HexDecoder decryptor(new StreamTransformationFilter(cbcDecryption, new StringSink(outstr)));  
    decryptor.Put((byte *)cipherText, strlen(cipherText));  
    decryptor.MessageEnd();  
      
    return outstr;  
}  

std::string CBC_CTS_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText)
{
    std::string outstr;
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
    //填iv  
    byte iv[AES::BLOCKSIZE];  
    memset(iv,0x30,AES::BLOCKSIZE); 
sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);
      
    AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);  
      
    CBC_CTS_Mode_ExternalCipher::Encryption cbcctsEncryption(aesEncryption, iv);  
      
    StreamTransformationFilter cbcctsEncryptor(cbcctsEncryption, new HexEncoder(new StringSink(outstr)));  
    cbcctsEncryptor.Put((byte *)plainText, strlen(plainText));  
    cbcctsEncryptor.MessageEnd();  
      
    return outstr;  
}  




std::string CBC_CTS_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText)  
{  
    std::string outstr;  
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
    //填iv  
    byte iv[AES::BLOCKSIZE];  
    memset(iv,0x30,AES::BLOCKSIZE);  
sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);


    CBC_CTS_Mode<AES >::Decryption cbcctsDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);  
          
    HexDecoder decryptor(new StreamTransformationFilter(cbcctsDecryption, new StringSink(outstr)));  
    decryptor.Put((byte *)cipherText, strlen(cipherText));  
    decryptor.MessageEnd();  
      
    return outstr;  
}  










std::string CFB_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText)
{
    std::string outstr;
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
    //填iv  
    byte iv[AES::BLOCKSIZE];  
    memset(iv,0x30,AES::BLOCKSIZE); 
sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);
      
    AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);  
      
    CFB_Mode_ExternalCipher::Encryption cfbEncryption(aesEncryption, iv);  
      
    StreamTransformationFilter cfbEncryptor(cfbEncryption, new HexEncoder(new StringSink(outstr)));  
    cfbEncryptor.Put((byte *)plainText, strlen(plainText));  
    cfbEncryptor.MessageEnd();  
      
    return outstr;  
}  




std::string CFB_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText)  
{  
    std::string outstr;  
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
    //填iv  
    byte iv[AES::BLOCKSIZE];  
    memset(iv,0x30,AES::BLOCKSIZE);  
sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);


    CFB_Mode<AES >::Decryption cfbDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);  
          
    HexDecoder decryptor(new StreamTransformationFilter(cfbDecryption, new StringSink(outstr)));  
    decryptor.Put((byte *)cipherText, strlen(cipherText));  
    decryptor.MessageEnd();  
      
    return outstr;  
}  




std::string OFB_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText)
{
    std::string outstr;
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
    //填iv  
    byte iv[AES::BLOCKSIZE];  
    memset(iv,0x30,AES::BLOCKSIZE); 
sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);
      
    AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);  
      
    OFB_Mode_ExternalCipher::Encryption ofbEncryption(aesEncryption, iv);  
      
    StreamTransformationFilter ofbEncryptor(ofbEncryption, new HexEncoder(new StringSink(outstr)));  
    ofbEncryptor.Put((byte *)plainText, strlen(plainText));  
    ofbEncryptor.MessageEnd();  
      
    return outstr;  
}  




std::string OFB_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText)  
{  
    std::string outstr;  
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
    //填iv  
    byte iv[AES::BLOCKSIZE];  
    memset(iv,0x30,AES::BLOCKSIZE);  
sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);


    OFB_Mode<AES >::Decryption ofbDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);  
          
    HexDecoder decryptor(new StreamTransformationFilter(ofbDecryption, new StringSink(outstr)));  
    decryptor.Put((byte *)cipherText, strlen(cipherText));  
    decryptor.MessageEnd();  
      
    return outstr;  
}  


std::string CTR_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText)
{
    std::string outstr;
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
    //填iv  
    byte iv[AES::BLOCKSIZE];  
    memset(iv,0x30,AES::BLOCKSIZE); 
sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);
      
    AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);  
      
    CTR_Mode_ExternalCipher::Encryption ctrEncryption(aesEncryption, iv);  
      
    StreamTransformationFilter ctrEncryptor(ctrEncryption, new HexEncoder(new StringSink(outstr)));  
    ctrEncryptor.Put((byte *)plainText, strlen(plainText));  
    ctrEncryptor.MessageEnd();  
      
    return outstr;  
}  




std::string CTR_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText)  
{  
    std::string outstr;  
      
    //填key  
    SecByteBlock key(AES::MAX_KEYLENGTH);  
    memset(key,0x30,key.size() );  
    sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);  
          
    //填iv  
    byte iv[AES::BLOCKSIZE];  
    memset(iv,0x30,AES::BLOCKSIZE);  
sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);


    CTR_Mode<AES >::Decryption ctrDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);  
          
    HexDecoder decryptor(new StreamTransformationFilter(ctrDecryption, new StringSink(outstr)));  
    decryptor.Put((byte *)cipherText, strlen(cipherText));  
    decryptor.MessageEnd();  
      
    return outstr;  
}  


int _tmain(int argc, _TCHAR* argv[])
{
string plainText = "This Program shows how to use ECB, CBC, CBC_CTS, CFB, OFB and CTR mode of AES in Crypto++.";
string aesKey = "0123456789ABCDEF0123456789ABCDEF";//256bits, also can be 128 bits or 192bits
string aesIV = "ABCDEF0123456789";//128 bits
string ECB_EncryptedText,ECB_DecryptedText,
CBC_EncryptedText,CBC_DecryptedText,
CBC_CTS_EncryptedText,CBC_CTS_DecryptedText,
CFB_EncryptedText,CFB_DecryptedText,
OFB_EncryptedText,OFB_DecryptedText,
CTR_EncryptedText,CTR_DecryptedText;


//ECB
ECB_EncryptedText = ECB_AESEncryptStr(aesKey, plainText.c_str());//ECB加密
ECB_DecryptedText = ECB_AESDecryptStr(aesKey,ECB_EncryptedText.c_str());//ECB解密


//CBC
CBC_EncryptedText = CBC_AESEncryptStr(aesKey, aesIV, plainText.c_str());//CBC加密
CBC_DecryptedText = CBC_AESDecryptStr(aesKey, aesIV, CBC_EncryptedText.c_str());//CBC解密


//CBC_CTS
CBC_CTS_EncryptedText = CBC_CTS_AESEncryptStr(aesKey, aesIV, plainText.c_str());//CBC_CTS加密
CBC_CTS_DecryptedText = CBC_CTS_AESDecryptStr(aesKey, aesIV, CBC_CTS_EncryptedText.c_str());//CBC_CTS解密

//CFB
CFB_EncryptedText = CFB_AESEncryptStr(aesKey, aesIV, plainText.c_str());//CFB加密
CFB_DecryptedText = CFB_AESDecryptStr(aesKey, aesIV, CFB_EncryptedText.c_str());//CFB解密


//OFB
OFB_EncryptedText = OFB_AESEncryptStr(aesKey, aesIV, plainText.c_str());//OFB加密
OFB_DecryptedText = OFB_AESDecryptStr(aesKey, aesIV, OFB_EncryptedText.c_str());//OFB解密


//CTR
CTR_EncryptedText = CTR_AESEncryptStr(aesKey, aesIV, plainText.c_str());//CTR加密
CTR_DecryptedText = CTR_AESDecryptStr(aesKey, aesIV, CTR_EncryptedText.c_str());//CTR解密




cout << "Crypto++ AES-256 加密测试"<< endl;
cout << "分别使用ECB,CBC, CBC_CTR,CFB,OFB和CTR模式"<< endl;
cout << "加密用密钥:" << aesKey << endl;
cout << "密钥长度:" << AES::MAX_KEYLENGTH*8 <<"bits" << endl;
cout << "IV:" << aesIV << endl;
cout << endl;


cout << "ECB测试"<< endl;
cout << "原文:" << plainText << endl;
cout << "密文:" << ECB_EncryptedText << endl;
cout << "恢复明文:" << ECB_DecryptedText << endl << endl;

cout << "CBC测试"<< endl;
cout << "原文:" << plainText << endl;
cout << "密文:" << CBC_EncryptedText << endl;
cout << "恢复明文:" << CBC_DecryptedText << endl << endl;


cout << "CBC_CTS测试"<< endl;
cout << "原文:" << plainText << endl;
cout << "密文:" << CBC_CTS_EncryptedText << endl;
cout << "恢复明文:" << CBC_CTS_DecryptedText << endl << endl;


cout << "CFB测试"<< endl;
cout << "原文:" << plainText << endl;
cout << "密文:" << CFB_EncryptedText << endl;
cout << "恢复明文:" << CFB_DecryptedText << endl << endl;

cout << "OFB测试"<< endl;
cout << "原文:" << plainText << endl;
cout << "密文:" << OFB_EncryptedText << endl;
cout << "恢复明文:" << OFB_DecryptedText << endl << endl;


cout << "CTR测试"<< endl;
cout << "原文:" << plainText << endl;
cout << "密文:" << CTR_EncryptedText << endl;
cout << "恢复明文:" << CTR_DecryptedText << endl << endl;

getchar();
return 0;
}

2   2、设置工程属性

      选择工程属性(Alt + F7):

     (1)“Configuration Properties”→“C/C++” →“General”,右边的“Additional Include Directories”设置为上面建好的Crypto++ SDK的         Include文件夹,“C:\Program Files\CyptoPP\include”;

     (2) “Configuration Properties”→“Linker” →“General”,右边的“Additional Library Directories”设置为上面建好的Crypto++ SDK的Lib\Debug文件夹,“C:\Program Files\CyptoPP\lib\debug”(Release模式下对应着Release文件夹);

     (3) “Configuration Properties”→“C/C++” →“Code Generation”,右边的“Runtime Library”设置为“Multi-threaded Debug (/MTd)”(Release模式下对应着“Multi-threaded (/MT)”)

3、 运行程序 (Ctrl + F5)

输出结果如下:





版权声明:本文为happy423原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。