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

OpenSSL RSA解密报错:RSA_padding_check_PKCS1_type_2填充解码错误

解决OpenSSL RSA解密文件数据时的PKCS解码错误问题

我之前也碰到过一模一样的问题——内存里加解密好好的,一存文件再读出来就报PKCS解码错误,折腾了好一阵才搞明白,核心问题基本都是二进制数据在文件读写过程中被损坏了,给你列几个最可能的原因和解决办法:

1. 必须用二进制模式读写文件

这是最常见的坑!如果你的代码里用了fopen("xxx", "w")或者fopen("xxx", "r")这种文本模式,在Windows系统下会自动转换换行符(把0x0A变成0x0D0A),还会把0x1A当作EOF截断数据,直接把加密后的二进制数据搞乱。

一定要改成二进制模式:

// 写入加密数据
FILE *fp_write = fopen("encrypted_aes_key.bin", "wb");
// 读取加密数据
FILE *fp_read = fopen("encrypted_aes_key.bin", "rb");

2. 确保读写的字节数完全一致

RSA加密后的输出长度是固定的(等于你的RSA密钥模数长度,比如2048位密钥就是256字节),写入时要把完整的加密数据都写进去,读取时也要读够全部长度,别用fgets这种文本读取函数(它会在遇到\0时停止)。

举个正确的读写示例:

// 加密后写入文件
int enc_len = RSA_public_encrypt(
    aes_key_len, aes_key, enc_data, rsa_pub, RSA_PKCS1_PADDING
);
if (enc_len == -1) { /* 处理加密错误 */ }

FILE *fp = fopen("enc_data.bin", "wb");
if (!fp) { /* 处理文件打开错误 */ }
// 确保写入全部字节
if (fwrite(enc_data, 1, enc_len, fp) != enc_len) {
    fprintf(stderr, "写入文件时截断了数据!\n");
}
fclose(fp);

// 从文件读取后解密
fp = fopen("enc_data.bin", "rb");
if (!fp) { /* 处理错误 */ }
// 先获取文件大小
fseek(fp, 0, SEEK_END);
long file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);

unsigned char *read_enc_data = malloc(file_size);
if (!read_enc_data) { /* 处理内存分配错误 */ }
// 读取全部字节
if (fread(read_enc_data, 1, file_size, fp) != file_size) {
    fprintf(stderr, "读取文件时没读全数据!\n");
}
fclose(fp);

// 解密时用读取到的实际长度作为输入长度
int dec_len = RSA_private_decrypt(
    file_size, read_enc_data, dec_aes_key, rsa_priv, RSA_PKCS1_PADDING
);
if (dec_len == -1) { /* 处理解密错误 */ }

3. 别对二进制加密数据做多余的字符串处理

如果你为了存储把加密数据直接当作ASCII字符串处理(比如用strcpy或者printf输出),遇到不可打印字符(比如0x00到0x1F)就会截断或者乱码,导致数据损坏。如果需要把加密数据转成可安全存储的字符串,应该用Base64编码,写入前编码,读取后解码,再解密。

4. 验证读写前后的数据一致性

如果上面的步骤都做了还是报错,建议把加密后的内存数据和读取后的文件数据都打印成十六进制,对比两者是否完全相同:

// 打印十六进制的函数示例
void print_hex(const unsigned char *data, int len) {
    for (int i=0; i<len; i++) {
        printf("%02X ", data[i]);
        if ((i+1)%16 == 0) printf("\n");
    }
    printf("\n");
}

如果打印出来的内容不一样,说明读写过程有问题;如果完全一样,那就要检查解密时用的密钥是不是和加密时匹配,或者填充模式有没有写错(比如加密用了RSA_PKCS1_PADDING,解密用了别的模式)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:16:02