Crypto++ 是功能強大的 C++ 密碼學庫,但官方僅提供源碼與 Visual Studio 專案,無預編譯二進位。本文詳述 Windows + Visual Studio 環境下:編譯生成 `cryptlib.lib`、建立 SDK 目錄結構、配置專案屬性、實現 RSA 密鑰生成/加密/解密完整流程,並解決常見運行時庫衝突錯誤。
C:\Program Files\CryptoPP\
├── include\ # 所有 .h 檔
│ ├── aes.h
│ ├── rsa.h
│ └── ...
└── lib\
├── debug\ # Debug 版 cryptlib.lib
└── release\ # Release 版 cryptlib.lib
將源碼目錄下所有 `*.h` 複製到 `include\`,兩版 `.lib` 分別放入 `lib\debug\`、`lib\release\`。
右鍵專案 → **Properties** (Alt+F7):
| 配置節點 | 設置值 | 說明 |
|---|---|---|
| C/C++ → General → Additional Include Directories | `C:\Program Files\CryptoPP\include` | 頭文件搜尋路徑 |
| Linker → General → Additional Library Directories | Debug: `C:\Program Files\CryptoPP\lib\debug` Release: `C:\Program Files\CryptoPP\lib\release` | 庫文件搜尋路徑 |
| Linker → Input → Additional Dependencies | `cryptlib.lib` | 或代碼中 `#pragma comment(lib, "cryptlib.lib")` |
| C/C++ → Code Generation → Runtime Library | Debug: `/MTd` (多線程偵錯) Release: `/MT` (多線程) | 必須與 cryptlib 編譯時一致!否則鏈接錯誤 LNK2005 (多重定義 std::string 等) |
#include "randpool.h"
#include "rsa.h"
#include "hex.h"
#include "files.h"
#include
#include
using namespace std;
using namespace CryptoPP;
#pragma comment(lib, "cryptlib.lib")
RandomPool& GlobalRNG() {
static RandomPool pool;
return pool;
}
void GenerateRSAKey(unsigned int keyLen, const char* privFile, const char* pubFile, const char* seed) {
RandomPool rng;
rng.Put((byte*)seed, strlen(seed));
// 私鑰生成器
RSAES_OAEP_SHA_Decryptor priv(rng, keyLen);
HexEncoder privOut(new FileSink(privFile));
priv.DEREncode(privOut);
privOut.MessageEnd();
// 從私鑰導出公鑰
RSAES_OAEP_SHA_Encryptor pub(priv);
HexEncoder pubOut(new FileSink(pubFile));
pub.DEREncode(pubOut);
pubOut.MessageEnd();
}
string RSAEncryptString(const char* pubFile, const char* seed, const char* plaintext) {
FileSource pubSrc(pubFile, true, new HexDecoder); // true = pumpAll
RSAES_OAEP_SHA_Encryptor encryptor(pubSrc);
RandomPool rng;
rng.Put((byte*)seed, strlen(seed));
string ciphertext;
StringSource(plaintext, true,
new PK_EncryptorFilter(rng, encryptor,
new HexEncoder(new StringSink(ciphertext))
)
);
return ciphertext; // Hex 編碼字串
}
string RSADecryptString(const char* privFile, const char* ciphertext) {
FileSource privSrc(privFile, true, new HexDecoder);
RSAES_OAEP_SHA_Decryptor decryptor(privSrc);
string plaintext;
StringSource(ciphertext, true,
new HexDecoder(
new PK_DecryptorFilter(GlobalRNG(), decryptor,
new StringSink(plaintext)
)
)
);
return plaintext;
}
int main() {
const char* seed = "my_seed_123";
const char* pri = "private.key";
const char* pub = "public.key";
GenerateRSAKey(1024, pri, pub, seed);
const char* msg = "Hello Crypto++ RSA!";
cout << "Original: " << msg << endl;
string enc = RSAEncryptString(pub, seed, msg);
cout << "Encrypted (Hex): " << enc << endl;
string dec = RSADecryptString(pri, enc.c_str());
cout << "Decrypted: " << dec << endl;
return 0;
}
| 錯誤現象 | 原因 | 解決 |
|---|---|---|
| LNK2005: `std::basic_string...` already defined in `msvcprtd.lib` | 運行時庫不匹配:專案 `/MDd` (動態) vs `cryptlib` `/MTd` (靜態) | 專案 **Code Generation → Runtime Library** 統一為 `/MTd` (Debug) / `/MT` (Release) |
| 無法打開 `cryptlib.lib` | 庫路徑錯誤或未編譯對應配置 | 檢查 Linker → Library Directories,確認 Debug/Release 分別指向正確資料夾 |
| 運行時崩潰 `Access Violation` | 種子字串為空/過短,或密鑰文件損壞 | 種子建議 >16 字元;檢查 `FileSink` 輸出文件大小 >0 |
| 加密數據過長失敗 | RSA 直接加密長度限制 (KeySize/8 - 填充開銷),1024位約 117 位元組 | 長數據採用混合加密:AES 加密數據 + RSA 加密 AES Key |
完成上述配置,你即擁有一個可在 Windows Visual Studio 直接使用的 Crypto++ 開發環境,可專注於業務層密碼學邏輯而非構建系統糾結。