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

OpenSSL私钥解密偶现error:02000079:rsa routines::oaep解码错误求助

问题分析与修复:OpenSSL RSA加密解密随机失败

问题根源

核心错误出在解密时传入的密文长度计算错误:

int de_result=private_decrypt(encrypted, strlen((char *)encrypted), rsaPrivate, decrypted);

RSA加密后的结果是二进制数据,并非ASCII字符串,密文里可能随机包含\0(空字符)。strlen会在遇到第一个\0时停止计算长度,导致传入解密函数的长度比真实密文长度短,最终触发OAEP解码错误。由于\0的出现是随机的,所以流程会时好时坏。

此外还有两处次要问题:

  • createRSAWithFilename函数中,RSA *rsa = RSA_new();的初始化会被后续PEM_read_*的返回值覆盖,存在内存泄漏风险
  • 未检查密钥加载、加密解密的返回值,也未在程序结束时释放资源

修复方案

1. 传递正确的密文长度

加密成功后,en_result就是密文的实际长度(2048位RSA+OAEP填充的密文固定为256字节),解密时直接使用该值:

int de_result=private_decrypt(encrypted, en_result, rsaPrivate, decrypted);

2. 修复密钥加载函数的资源管理

调整createRSAWithFilename,正确关闭文件指针并初始化RSA对象:

RSA *createRSAWithFilename(const char *filename, int pub)
{
    FILE *fp = fopen(filename, "rb");
    if (fp == NULL)
    {
        printf("Unable to open file %s\n", filename);
        return NULL;
    }

    RSA *rsa = NULL;
    if (pub)
    {
        rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
    }
    else
    {
        rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
    }

    fclose(fp);
    return rsa;
}

3. 添加错误检查与资源释放

在main函数中增加返回值校验,并在程序结束时释放RSA对象:

int main()
{
    std::string textToBeEncoded="hi";
    unsigned char plaintext[1024] = {0};
    unsigned char encrypted[4098]= {0};
    unsigned char decrypted[4098]={0};
    strcpy((char *)plaintext,textToBeEncoded.c_str());

    RSA *rsaPublic=createRSAWithFilename("public.pem", 1);
    if (!rsaPublic) {
        fprintf(stderr, "Failed to load public key\n");
        return 1;
    }

    memset(encrypted,0,4098);
    int en_result=public_encrypt(plaintext, strlen((char *)plaintext), rsaPublic, encrypted);
    if (en_result == -1) {
        fprintf(stderr, "Encryption failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
        RSA_free(rsaPublic);
        return 1;
    }
    
    RSA *rsaPrivate=createRSAWithFilename("key.pem", 0);
    if (!rsaPrivate) {
        fprintf(stderr, "Failed to load private key\n");
        RSA_free(rsaPublic);
        return 1;
    }
  
    memset(decrypted,0,4098);   
    int de_result=private_decrypt(encrypted, en_result, rsaPrivate, decrypted);
    if (de_result == -1) {
        fprintf(stderr, "Decryption failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
        RSA_free(rsaPublic);
        RSA_free(rsaPrivate);
        return 1;
    }

    std::cout << "Result EN: " << en_result << std::endl;
    std::cout << "Result DE: " << de_result << std::endl;
    
    // 用实际解密长度初始化字符串,避免空字符截断
    std::string decryptedString = std::string((const char *)decrypted, de_result);
    std::cout << "DECRYPTED: " << decryptedString << " END." << std::endl;

    // 释放资源
    RSA_free(rsaPublic);
    RSA_free(rsaPrivate);

    return 0;
}

修复效果验证

修改后,加密解密流程将稳定运行,输出始终为:

Result EN: 256
Result DE: 2
DECRYPTED: hi END.

内容的提问来源于stack exchange,提问作者Dinhosaur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:55:22