使用OpenSSL的CMS_decrypt()解密失败,返回error:00000000求助
排查OpenSSL CMS_decrypt失败及错误码00000000的问题
1. 修复错误信息打印逻辑,获取真实错误
你当前的错误打印代码存在语法问题,且未正确遍历OpenSSL错误栈,导致拿到无效的错误信息:
// 原错误代码(引号未闭合、未循环获取完整错误栈) printf("openssl error [%s], ERR_error_string(ERR_get_error(), NULL)); // 替换为正确的错误打印逻辑 unsigned long err; while ((err = ERR_get_error()) != 0) { fprintf(stderr, "OpenSSL error: %s\n", ERR_error_string(err, NULL)); }
- OpenSSL操作失败时可能会压入多个错误信息,仅调用一次
ERR_get_error()无法获取完整错误栈;原代码的引号未闭合也会导致编译异常,进一步干扰错误信息输出。 - 改用循环遍历错误栈后,才能拿到真正的失败原因,替代当前无效的
error:00000000。
2. 补全前置步骤的错误检查(CMS结构解析可能已失败)
你当前对BIO_new_file和d2i_CMS_bio的错误处理仅打印简单提示,未排查OpenSSL错误,这两个步骤失败会直接导致后续解密失败:
in = BIO_new_file("cms_encrypted_output.txt", "r"); if (NULL == in) { fprintf(stderr, "BIO_new_file failed: "); unsigned long err; while ((err = ERR_get_error()) != 0) { fprintf(stderr, "%s ", ERR_error_string(err, NULL)); } fprintf(stderr, "\n"); return -1; // 终止流程,避免无意义的后续操作 } cms = d2i_CMS_bio(in , NULL); if (NULL == cms) { fprintf(stderr, "d2i_CMS_bio failed: "); unsigned long err; while ((err = ERR_get_error()) != 0) { fprintf(stderr, "%s ", ERR_error_string(err, NULL)); } fprintf(stderr, "\n"); BIO_free(in); return -1; }
- 如果
d2i_CMS_bio失败,说明CMS加密文件格式错误、损坏或读取不完整,后续CMS_decrypt必然失败;此时的无效错误码可能是因为前面的错误栈未清空,后续调用ERR_get_error()拿到的是空错误。
3. 验证私钥(rkey)和证书(rcert)的有效性
确保你正确加载了与加密公钥配对的私钥和对应证书:
- 私钥加载示例(需确保文件路径和格式正确):
BIO *key_bio = BIO_new_file("private_key.pem", "r"); if (!key_bio) { /* 处理文件打开错误 */ } EVP_PKEY *rkey = PEM_read_bio_PrivateKey(key_bio, NULL, NULL, NULL); BIO_free(key_bio); if (!rkey) { /* 打印OpenSSL错误并终止 */ } - 证书加载示例:
BIO *cert_bio = BIO_new_file("cert.pem", "r"); if (!cert_bio) { /* 处理文件打开错误 */ } X509 *rcert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL); BIO_free(cert_bio); if (!rcert) { /* 打印OpenSSL错误并终止 */ } - 如果
rkey/rcert为NULL,或与加密密钥不匹配,CMS_decrypt会失败,且可能因错误栈未正确填充导致无效错误码。
4. 检查输出BIO(out)的初始化
确保out已正确创建,用于写入解密后的内容:
BIO *out = BIO_new_file("decrypted_output.txt", "w"); if (!out) { /* 处理文件创建错误,终止流程 */ }
- 如果
out为NULL,CMS_decrypt会直接失败,且可能无法生成有效错误信息。
5. 验证CMS加密文件的完整性
先用OpenSSL命令行工具验证文件是否有效:
openssl cms -in cms_encrypted_output.txt -inform PEM -decrypt -inkey private_key.pem -out test_decrypt.txt
- 如果命令行解密失败,说明文件本身存在问题(格式错误、损坏、非CMS加密数据);如果命令行成功,说明代码中的加载或参数处理存在问题。
内容的提问来源于stack exchange,提问作者asdf1234
相关产品推荐
相关产品推荐

