You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:58:11