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):

shell
cl /LD rsa_crypto.cpp /I"path\to\openssl\include" /link /LIBPATH:"path\to\openssl\lib" -lssl -lcrypto

Linux(使用 g++):

shell
g++ -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, 加密, 解密