C++调用Openssl 报OPENSSL_Uplink(503EE220,08): no OPENSSL_Applink

发布于:2025-03-31 ⋅ 阅读:(21) ⋅ 点赞:(0)

严重性 代码 说明 项目 文件 行 禁止显示状态
错误 C4996 ‘PEM_read_ECPrivateKey’: Since OpenSSL 3.0 ConsoleApplication9 C:\Users\FT\source\repos\ConsoleApplication9\ConsoleApplication9\ConsoleApplication9.cpp 23
错误 C4996 ‘fopen’: This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. ConsoleApplication9 C:\Users\FT\source\repos\ConsoleApplication9\ConsoleApplication9\ConsoleApplication9.cpp 16
错误 C4996 ‘EC_KEY_free’: Since OpenSSL 3.0 ConsoleApplication9 C:\Users\FT\source\repos\ConsoleApplication9\ConsoleApplication9\ConsoleApplication9.cpp 51

你遇到的错误主要来自两个方面:OpenSSL 3.0的API弃用和Microsoft CRT的安全警告。以下是解决方案:

1. OpenSSL 3.0 API弃用问题

OpenSSL 3.0对低级别API进行了重构,推荐使用更高层次的EVP API。对于EC密钥操作:

// 替换 PEM_read_ECPrivateKey 和 EC_KEY_free
#include <openssl/evp.h>
#include <openssl/pem.h>

// 读取私钥
EVP_PKEY* pkey = NULL;
FILE* fp = fopen("private.pem", "r");
if (!fp) { /* 错误处理 */ }

pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
fclose(fp);

if (!pkey) { /* 错误处理 */ }

// 使用pkey...

// 释放资源
EVP_PKEY_free(pkey);

2. Microsoft CRT安全警告

对于fopen的警告,你有几个选择:

选项1:使用推荐的fopen_s

FILE* fp = NULL;
errno_t err = fopen_s(&fp, "private.pem", "r");
if (err != 0 || !fp) { /* 错误处理 */ }

选项2:禁用警告(在文件开头)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

选项3:项目属性设置

  1. 右键项目 → 属性
  2. C/C++ → 预处理器 → 预处理器定义
  3. 添加_CRT_SECURE_NO_WARNINGS

完整示例代码

#define _CRT_SECURE_NO_WARNINGS
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <stdio.h>

int main() {
    // 读取私钥
    FILE* fp = fopen("private.pem", "r");
    if (!fp) {
        perror("无法打开文件");
        return 1;
    }

    EVP_PKEY* pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
    fclose(fp);

    if (!pkey) {
        fprintf(stderr, "无法读取私钥\n");
        return 1;
    }

    // 在这里使用pkey...

    // 清理
    EVP_PKEY_free(pkey);
    return 0;
}

其他注意事项

  1. 确保你链接的是OpenSSL 3.0或更高版本

  2. 检查你的头文件路径和库文件路径是否正确

  3. 如果必须使用旧的EC_KEY API,可以定义:

    #define OPENSSL_API_COMPAT 10100  // 使用1.1.0兼容模式
    

    但这不推荐作为长期解决方案

  4. 编译时需要链接正确的库,通常添加:

    -llibcrypto -llibssl
    

这些修改应该能解决你遇到的编译错误。

解决OPENSSL_Uplink(503EE220,08): no OPENSSL_Applink

你的错误:

OPENSSL_Uplink(51EEE220,08): no OPENSSL_Applink

通常发生在 Windows 环境下 使用 MinGW 编译 OpenSSL 代码,并且 代码中缺少 OPENSSL_Applink() 时。


📌 解决方案

方法 1️⃣:添加 #include <openssl/applink.c>

在你的 load_ec_key_from_pem.cpp 文件开头 添加:

#include <openssl/applink.c>

完整代码:

#include <openssl/applink.c>  // 解决 OPENSSL_Uplink 错误
#include <openssl/pem.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <iostream>
#include <string>

#define PRIVATE_KEY_PASSWORD "123123"  // 设置密钥密码

void handleErrors() {
    ERR_print_errors_fp(stderr);
    abort();
}

// 读取 PEM 格式的 EC 私钥
EC_KEY* load_ec_key_from_pem(const std::string& filename) {
    FILE* fp = fopen(filename.c_str(), "r");
    if (!fp) {
        std::cerr << "Failed to open PEM file: " << filename << std::endl;
        return nullptr;
    }

    // 读取 EC 私钥,提供密码
    EC_KEY* ec_key = PEM_read_ECPrivateKey(fp, nullptr, nullptr, (void*)PRIVATE_KEY_PASSWORD);
    fclose(fp);

    if (!ec_key) {
        std::cerr << "Failed to read EC private key from PEM file: " << filename << std::endl;
        ERR_print_errors_fp(stderr);
    } else {
        std::cout << "Successfully loaded EC private key!" << std::endl;
    }

    return ec_key;
}

int main() {
    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();

    std::string pem_file = "CA_key_enc.pem";  // 你的加密私钥文件
    EC_KEY* ec_key = load_ec_key_from_pem(pem_file);

    if (!ec_key) {
        std::cerr << "Error: Unable to load encrypted EC key!" << std::endl;
        return -1;
    }

    std::cout << "EC Key successfully loaded!" << std::endl;

    EC_KEY_free(ec_key);
    EVP_cleanup();
    ERR_free_strings();

    return 0;
}

方法 2️⃣:在编译时添加 -DOPENSSL_USE_APPLINK

如果你不想在代码里添加 #include <openssl/applink.c>,可以在 编译时 加入:

g++ -o load_ec_key load_ec_key.cpp -lssl -lcrypto -DOPENSSL_USE_APPLINK

📌 为什么会报 no OPENSSL_Applink

  • Windows 平台 使用 MinGW 时,OpenSSL 需要 OPENSSL_Applink() 来支持 FILE* 相关的 API 调用,否则 PEM_read_ECPrivateKey() 会崩溃。
  • applink.c 提供 OPENSSL_Applink(),让 OpenSSL 处理 FILE* 相关的 I/O 操作。

📌 现在你可以成功读取 CA_key.pem 了! 🚀

有问题欢迎继续问!🔥