使用Crypto++时遇InvertibleRSAFunction和X509PublicKey未定义引用求助
解决Crypto++中
InvertibleRSAFunction和X509PublicKey未定义引用错误(附Alice&Bob安全通信示例) 这个未定义引用的坑我之前帮好几个开发者踩过,本质就是编译阶段能找到头文件,但链接阶段没关联上Crypto++的库文件。先给你把核心解决方法说清楚,再结合你Alice和Bob安全通信的需求给个完整可运行示例。
一、核心问题:链接阶段缺失Crypto++库
报错的根源是:编译器能找到InvertibleRSAFunction和X509PublicKey的头文件声明,但链接时找不到这些类的实现代码(也就是库文件里的二进制代码)。根据你用的构建工具,对应解决方案如下:
1. 用CMake构建的情况
在你的CMakeLists.txt里添加这几行,确保正确找到并链接Crypto++库:
# 查找系统中的Crypto++库 find_package(CryptoPP REQUIRED) # 将库链接到你的目标项目 target_link_libraries(你的项目名称 PRIVATE CryptoPP::CryptoPP)
2. 直接用g++/clang++编译的情况
编译命令末尾必须加链接参数,指定Crypto++库:
g++ your_rsa_code.cpp -o rsa_communication -lcryptopp
如果是Windows平台用MSVC编译,需要手动把Crypto++的cryptlib.lib添加到项目的「链接器->输入」列表里,或者在编译命令后加/link cryptlib.lib参数。
二、Alice&Bob安全通信完整示例代码
下面是完全符合你需求的实现:Alice生成RSA密钥对并导出公钥,Bob用公钥加密消息+生成SHA256摘要(保证完整性)写入文件,Alice读取文件后解密并验证消息完整性。
#include <iostream> #include <fstream> #include <string> #include <cryptopp/rsa.h> #include <cryptopp/osrng.h> #include <cryptopp/base64.h> #include <cryptopp/sha.h> #include <cryptopp/hex.h> using namespace CryptoPP; // 生成2048位RSA密钥对 void GenerateRSAKeys(RSA::PrivateKey& privateKey, RSA::PublicKey& publicKey) { AutoSeededRandomPool rng; InvertibleRSAFunction keyParams; keyParams.GenerateRandomWithKeySize(rng, 2048); privateKey = RSA::PrivateKey(keyParams); publicKey = RSA::PublicKey(keyParams); } // 将公钥以X509格式保存到文件 void SavePublicKey(const RSA::PublicKey& publicKey, const std::string& filename) { std::ofstream outFile(filename, std::ios::binary); if (!outFile.is_open()) { throw std::runtime_error("Failed to open public key file for writing"); } X509PublicKey x509PubKey; x509PubKey.Load(publicKey); x509PubKey.Save(outFile); } // 从文件加载X509格式的公钥 void LoadPublicKey(RSA::PublicKey& publicKey, const std::string& filename) { std::ifstream inFile(filename, std::ios::binary); if (!inFile.is_open()) { throw std::runtime_error("Failed to open public key file for reading"); } X509PublicKey x509PubKey; x509PubKey.Load(inFile); x509PubKey.AccessPublicKey().TransferTo(publicKey); } // 加密消息+生成SHA256摘要(完整性保护),写入文件 void EncryptWithIntegrity(const std::string& plaintext, const RSA::PublicKey& pubKey, const std::string& outputFile) { AutoSeededRandomPool rng; std::string ciphertext, combinedData, encodedData; // 1. 计算明文的SHA256摘要(用于后续完整性验证) SHA256 hash; std::string digest; digest.resize(hash.DigestSize()); hash.Update((const byte*)plaintext.data(), plaintext.size()); hash.Final((byte*)digest.data()); // 2. 组合明文和摘要,用RSA-OAEP算法加密 combinedData = plaintext + digest; RSAES_OAEP_SHA_Encryptor encryptor(pubKey); ciphertext.resize(encryptor.CiphertextLength(combinedData.size())); encryptor.Encrypt(rng, (const byte*)combinedData.data(), combinedData.size(), (byte*)ciphertext.data()); // 3. Base64编码后写入文件(避免二进制存储乱码) StringSource(ciphertext, true, new Base64Encoder(new StringSink(encodedData))); std::ofstream outFile(outputFile); outFile << encodedData; } // 解密文件内容+验证消息完整性 std::string DecryptAndVerify(const std::string& inputFile, const RSA::PrivateKey& privKey) { AutoSeededRandomPool rng; std::string encodedData, ciphertext, combinedData, plaintext, receivedDigest; // 1. 读取文件中的Base64编码数据并解码 std::ifstream inFile(inputFile); std::getline(inFile, encodedData); StringSource(encodedData, true, new Base64Decoder(new StringSink(ciphertext))); // 2. RSA-OAEP解密 RSAES_OAEP_SHA_Decryptor decryptor(privKey); combinedData.resize(decryptor.MaxPlaintextLength(ciphertext.size())); size_t plainSize = decryptor.Decrypt(rng, (const byte*)ciphertext.data(), ciphertext.size(), (byte*)combinedData.data()); combinedData.resize(plainSize); // 3. 拆分明文和摘要(SHA256固定32字节) receivedDigest = combinedData.substr(combinedData.size() - 32); plaintext = combinedData.substr(0, combinedData.size() - 32); // 4. 重新计算明文摘要,验证完整性 SHA256 hash; std::string calculatedDigest; calculatedDigest.resize(hash.DigestSize()); hash.Update((const byte*)plaintext.data(), plaintext.size()); hash.Final((byte*)calculatedDigest.data()); if (receivedDigest != calculatedDigest) { throw std::runtime_error("Message tampered with! Integrity check failed."); } return plaintext; } int main() { try { // Alice生成RSA密钥对并导出公钥 RSA::PrivateKey alicePrivKey; RSA::PublicKey alicePubKey; GenerateRSAKeys(alicePrivKey, alicePubKey); SavePublicKey(alicePubKey, "alice_pub.key"); std::cout << "Alice generated RSA keys. Public key saved to alice_pub.key\n"; // Bob加载Alice的公钥,加密消息并写入文件 std::string bobMsg = "Hi Alice! This is a top-secret message with integrity protection."; RSA::PublicKey bobLoadedPubKey; LoadPublicKey(bobLoadedPubKey, "alice_pub.key"); EncryptWithIntegrity(bobMsg, bobLoadedPubKey, "encrypted_msg.txt"); std::cout << "Bob encrypted message and saved to encrypted_msg.txt\n"; // Alice读取文件,解密并验证完整性 std::string aliceReceived = DecryptAndVerify("encrypted_msg.txt", alicePrivKey); std::cout << "\nAlice received valid message:\n" << aliceReceived << "\n"; } catch (const std::exception& e) { std::cerr << "Error occurred: " << e.what() << "\n"; return 1; } return 0; }
三、额外注意事项
- 确保你的Crypto版本和代码兼容:最新版Crypto完全支持上述代码,旧版本可能在
InvertibleRSAFunction的用法上略有差异。 - 动态库运行时依赖:如果使用Crypto++动态库,要确保运行时系统能找到对应的动态链接库(比如Windows的
cryptopp.dll,Linux的libcryptopp.so)。 - 真实场景密钥分发:示例中直接传公钥文件是模拟场景,真实环境应该用CA签名公钥,或通过Diffie-Hellman密钥交换来保证公钥的真实性。
内容的提问来源于stack exchange,提问作者Razmode
相关产品推荐
相关产品推荐

