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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 05:33:58