源代碼:
下載
一. 下載Crypto++ Library
二. 建立自己使用的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.4版本。
Build時方法是,右擊Solution Explorer中的cryptlib工程,單擊build。第一次時它會報錯說“d:/cryptopp54/adler32.cpp(3) : fatal error C1033: cannot open program database 'd:/cryptopp54/win32/cryptlib/debug/vc80.idb'”,沒關係,按這樣再build一次,就可以build成功了。
2. 建立Crypto++ SDK
在C:/Program Files/中新建文件夾,取名“CryptoPP”,裏面新建文件夾“include”、“lib”,在“lib”中新建文件夾“debug”、“release”。將Crypto++庫中的所有頭文件複製到“include”文件夾中,再將上面生成的兩個cryptlib.lib分別複製到“debug”和“release”中。
三. RSA加解密
1.
在VS 2005中新建Win32 Console Application工程,建立空的工程。完成後新建文件main.cpp,裏面源碼如下:
#include "randpool.h"
#include "rsa.h"
#include "hex.h"
#include "files.h"
#include <iostream>
using namespace std;
using namespace CryptoPP;
#pragma comment(lib, "cryptlib.lib")
//------------------------
// 函數聲明
//------------------------
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed);
string RSAEncryptString(const char *pubFilename, const char *seed, const char *message);
string RSADecryptString(const char *privFilename, const char *ciphertext);
RandomPool & GlobalRNG();
//------------------------
// 主程序
//------------------------
void main()
{
char priKey[128] = {0};
char pubKey[128] = {0};
char seed[1024] = {0};
// 生成 RSA 密鑰對
strcpy(priKey, "pri"); // 生成的私鑰文件
strcpy(pubKey, "pub"); // 生成的公鑰文件
strcpy(seed, "seed");
GenerateRSAKey(1024, priKey, pubKey, seed);
// RSA 加解密
char message[1024] = {0};
cout<<"Origin Text:/t"<<"Hello World!"<<endl<<endl;
strcpy(message, "Hello World!");
string encryptedText = RSAEncryptString(pubKey, seed, message); // RSA 加密
cout<<"Encrypted Text:/t"<<encryptedText<<endl<<endl;
string decryptedText = RSADecryptString(priKey, encryptedText.c_str()); // RSA 解密
cout<<"Decrypted Text:/t"<<decryptedText<<endl<<endl;
}
//------------------------
// 生成RSA密鑰對
//------------------------
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
{
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));
RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
HexEncoder privFile(new FileSink(privFilename));
priv.DEREncode(privFile);
privFile.MessageEnd();
RSAES_OAEP_SHA_Encryptor pub(priv);
HexEncoder pubFile(new FileSink(pubFilename));
pub.DEREncode(pubFile);
pubFile.MessageEnd();
}
//------------------------
// RSA加密
//------------------------
string RSAEncryptString(const char *pubFilename, const char *seed, const char *message)
{
FileSource pubFile(pubFilename, true, new HexDecoder);
RSAES_OAEP_SHA_Encryptor pub(pubFile);
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));
string result;
StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
return result;
}
//------------------------
// RSA解密
//------------------------
string RSADecryptString(const char *privFilename, const char *ciphertext)
{
FileSource privFile(privFilename, true, new HexDecoder);
RSAES_OAEP_SHA_Decryptor priv(privFile);
string result;
StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))));
return result;
}
//------------------------
// 定義全局的隨機數池
//------------------------
RandomPool & GlobalRNG()
{
static RandomPool randomPool;
return randomPool;
}
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)
正常運行的輸出結果爲:
Origin Text: Hello World!
Encrypted Text: 79C72A482482EF45111F961772456310792AB735ECF72329ECB26292D2B26374
824E0E35D24A63CB03B867DD2C70B001FD4B2B33FBC984BD229A5226F284B889901817976A680322
9E8351372C5E28E8BEBA2A94E7CF61A8A162F0BA2F3E0C35D26842D92EC4866D25E6BF878743E481
84D9F6FF9BA690F953568D017C02D540
Decrypted Text: Hello World!
如果上面的第(3)步沒有設置則會出現以下鏈接錯誤:
cryptlib.lib(randpool.obj) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(char const *)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z) already defined in msvcprtd.lib(MSVCP80D.dll)
說在msvcprtd.lib和MSVCRTD.lib中已經定義過。