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
相关产品推荐
相关产品推荐

