严重性 代码 说明 项目 文件 行 禁止显示状态
错误 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:项目属性设置
- 右键项目 → 属性
- C/C++ → 预处理器 → 预处理器定义
- 添加
_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;
}
其他注意事项
确保你链接的是OpenSSL 3.0或更高版本
检查你的头文件路径和库文件路径是否正确
如果必须使用旧的EC_KEY API,可以定义:
#define OPENSSL_API_COMPAT 10100 // 使用1.1.0兼容模式
但这不推荐作为长期解决方案
编译时需要链接正确的库,通常添加:
-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
了! 🚀
有问题欢迎继续问!🔥