C++实现RSA加解密的动态链接库
C++ 实现 RSA 加解密的动态链接库
RSA 是一种非对称加密算法,广泛用于数据加密和数字签名。为了在 C++ 中实现 RSA 加解密功能,并将其封装为动态链接库(DLL),可以按照以下步骤进行操作:
1. 设置开发环境
确保你的开发环境已经配置好,通常包括:
- 编译器(如 MSVC、GCC)
- C++ 标准库(支持 C++11 或更高)
- OpenSSL 库(用于处理 RSA 加解密)
2. 安装 OpenSSL
RSA 算法的实现通常使用 OpenSSL 库,它提供了加密和解密的 API。你可以从 OpenSSL 官网下载并安装 OpenSSL 库。
安装 OpenSSL:
- Windows: 下载预编译的 OpenSSL 二进制文件或自行编译。
- Linux: 使用包管理器安装,如
sudo apt-get install libssl-dev
。
3. 创建 C++ 动态链接库项目
以下是一个简单的示例,展示了如何使用 OpenSSL 实现 RSA 加解密,并封装为 DLL。
1. 编写头文件 (rsa_crypto.h
)
定义 RSA 加解密接口:
cpp#ifndef RSA_CRYPTO_H
#define RSA_CRYPTO_H
#ifdef _WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
#include <string>
extern "C" {
EXPORT bool generate_key_pair(const std::string& pubKeyFile, const std::string& privKeyFile);
EXPORT std::string encrypt(const std::string& publicKeyFile, const std::string& plaintext);
EXPORT std::string decrypt(const std::string& privateKeyFile, const std::string& ciphertext);
}
#endif // RSA_CRYPTO_H
2. 实现文件 (rsa_crypto.cpp
)
实现 RSA 加解密功能:
cpp#include "rsa_crypto.h"
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <fstream>
#include <iostream>
bool generate_key_pair(const std::string& pubKeyFile, const std::string& privKeyFile) {
RSA* rsa = RSA_new();
BIGNUM* bn = BN_new();
BN_set_word(bn, RSA_F4);
if (RSA_generate_key_ex(rsa, 2048, bn, nullptr) != 1) {
ERR_print_errors_fp(stderr);
RSA_free(rsa);
BN_free(bn);
return false;
}
// Save private key
FILE* privKeyFilePtr = fopen(privKeyFile.c_str(), "wb");
if (!privKeyFilePtr) {
perror("Unable to open private key file");
RSA_free(rsa);
BN_free(bn);
return false;
}
PEM_write_RSAPrivateKey(privKeyFilePtr, rsa, nullptr, nullptr, 0, nullptr, nullptr);
fclose(privKeyFilePtr);
// Save public key
FILE* pubKeyFilePtr = fopen(pubKeyFile.c_str(), "wb");
if (!pubKeyFilePtr) {
perror("Unable to open public key file");
RSA_free(rsa);
BN_free(bn);
return false;
}
PEM_write_RSAPublicKey(pubKeyFilePtr, rsa);
fclose(pubKeyFilePtr);
RSA_free(rsa);
BN_free(bn);
return true;
}
std::string encrypt(const std::string& publicKeyFile, const std::string& plaintext) {
RSA* rsa = RSA_new();
FILE* pubKeyFilePtr = fopen(publicKeyFile.c_str(), "rb");
if (!pubKeyFilePtr) {
perror("Unable to open public key file");
return "";
}
PEM_read_RSAPublicKey(pubKeyFilePtr, &rsa, nullptr, nullptr);
fclose(pubKeyFilePtr);
std::string ciphertext(RSA_size(rsa), '\0');
int len = RSA_public_encrypt(plaintext.size(), reinterpret_cast<const unsigned char*>(plaintext.c_str()),
reinterpret_cast<unsigned char*>(&ciphertext[0]), rsa, RSA_PKCS1_OAEP_PADDING);
RSA_free(rsa);
if (len == -1) {
ERR_print_errors_fp(stderr);
return "";
}
ciphertext.resize(len);
return ciphertext;
}
std::string decrypt(const std::string& privateKeyFile, const std::string& ciphertext) {
RSA* rsa = RSA_new();
FILE* privKeyFilePtr = fopen(privateKeyFile.c_str(), "rb");
if (!privKeyFilePtr) {
perror("Unable to open private key file");
return "";
}
PEM_read_RSAPrivateKey(privKeyFilePtr, &rsa, nullptr, nullptr);
fclose(privKeyFilePtr);
std::string plaintext(RSA_size(rsa), '\0');
int len = RSA_private_decrypt(ciphertext.size(), reinterpret_cast<const unsigned char*>(ciphertext.c_str()),
reinterpret_cast<unsigned char*>(&plaintext[0]), rsa, RSA_PKCS1_OAEP_PADDING);
RSA_free(rsa);
if (len == -1) {
ERR_print_errors_fp(stderr);
return "";
}
plaintext.resize(len);
return plaintext;
}
3. 编译动态链接库
使用适当的编译命令编译生成 DLL 文件:
Windows(使用 MSVC):
shellcl /LD rsa_crypto.cpp /I"path\to\openssl\include" /link /LIBPATH:"path\to\openssl\lib" -lssl -lcrypto
Linux(使用 g++):
shellg++ -shared -o librsa_crypto.so rsa_crypto.cpp -I/usr/include/openssl -L/usr/lib -lssl -lcrypto
4. 使用 DLL
在其他 C++ 程序中,可以通过 #include "rsa_crypto.h"
和适当的链接选项来使用这个动态链接库。
示例代码:
cpp#include <iostream>
#include "rsa_crypto.h"
int main() {
std::string pubKeyFile = "public.pem";
std::string privKeyFile = "private.pem";
std::string plaintext = "Hello, RSA!";
if (generate_key_pair(pubKeyFile, privKeyFile)) {
std::cout << "Keys generated successfully.\n";
std::string ciphertext = encrypt(pubKeyFile, plaintext);
std::cout << "Encrypted text: " << ciphertext << "\n";
std::string decrypted = decrypt(privKeyFile, ciphertext);
std::cout << "Decrypted text: " << decrypted << "\n";
} else {
std::cerr << "Key generation failed.\n";
}
return 0;
}
总结
本教程展示了如何使用 OpenSSL 实现 RSA 加解密,并将其封装为 C++ 动态链接库。我们定义了头文件,编写了实现文件,编译生成 DLL,并在其他 C++ 程序中调用。通过这些步骤,你可以在 C++ 中实现 RSA 加解密,并利用动态链接库的方式进行封装和复用。
关键字
RSA, C++, 动态链接库, OpenSSL, 加解密, 公钥, 私钥, 编译, DLL, 加密, 解密