使用EVP_CIPHER_CTX加密字典找密钥时遇存储错误及段错误求助
解决EVP_CIPHER_CTX相关编译错误与内存问题
问题根源
你遇到的问题核心是OpenSSL版本兼容性差异:
- 在OpenSSL 1.1.0及后续版本中,
EVP_CIPHER_CTX被改为不透明结构体(opaque struct),编译器无法获取其内部存储大小,因此不能直接在栈上声明变量,这就是storage size of 'ctx' isn't known错误的原因。 - 旧版的
EVP_CIPHER_CTX_init函数已被废弃,直接调用会触发未定义行为,进而导致段错误、存储错误这类内存问题。
修复方案
1. 适配新版OpenSSL(1.1.0+)
使用官方推荐的动态分配+自动初始化API,完全替代旧写法:
// 动态分配上下文,同时完成初始化 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); if (!ctx) { // 处理内存分配失败的情况,比如打印错误日志或返回错误码 return -1; } // 初始化加密/解密流程(以AES-256-CBC为例) if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { // 初始化失败时先释放上下文,再处理错误 EVP_CIPHER_CTX_free(ctx); return -1; } // 执行加密/解密操作... // 操作完成后必须释放上下文,避免内存泄漏 EVP_CIPHER_CTX_free(ctx);
2. 兼容旧版OpenSSL(1.0.x)
如果代码需要同时支持旧版本,可以通过条件编译适配:
#if OPENSSL_VERSION_NUMBER < 0x10100000L EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); #else EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); if (!ctx) { /* 错误处理逻辑 */ } #endif // 加密/解密业务代码... #if OPENSSL_VERSION_NUMBER < 0x10100000L EVP_CIPHER_CTX_cleanup(&ctx); #else EVP_CIPHER_CTX_free(ctx); #endif
关键注意事项
- 务必检查
EVP_CIPHER_CTX_new()的返回值,空指针操作是段错误的常见诱因。 - 上下文使用完毕后必须释放,否则会造成内存泄漏。
- 编译时确保链接的OpenSSL库版本与代码API匹配,可通过
-lssl -lcrypto链接库,添加-DOPENSSL_API_COMPAT=0x10100000L强制使用新版API规范。
内容的提问来源于stack exchange,提问作者Samantha Figueroa
相关产品推荐
相关产品推荐

