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

Rust中OpenSSL RSA使用PKCS1_OAEP填充运行报错求助

RSA私钥加密切换PKCS1_OAEP/PSS填充报错的解决方法

问题描述

原本使用标准PKCS1填充进行RSA加密一切正常,切换为更安全的PKCS1_OAEP或PSS填充方案后,代码可编译但出现运行时错误。

代码示例

use openssl::{rsa::{Rsa, Padding}, symm::Cipher};
use bincode;

fn main() {
    let rsa = Rsa::generate(512).unwrap();
    let password = "password";
    let source = "hello paul".to_string();
    let data = bincode::serialize(&source).unwrap();
    let private = rsa.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), password.as_bytes()).unwrap();

    //encrypt
    let private_key = Rsa::private_key_from_pem_passphrase(&private, password.as_bytes()).unwrap();

    let mut enc_data = vec![0; private_key.size() as usize];
    match private_key.private_encrypt(&data, &mut enc_data, Padding::PKCS1_OAEP) {
        Ok(_) => {},
        Err(e) => {
            println!("{e}");
            return;
        }
    }
}

Cargo依赖配置

[dependencies]
openssl-sys = "0.9.79"
openssl = "0.10.44"
chrono = "0.4"
bincode = "1.0"
serde = { version = "1.0", features = ["derive"] }

报错信息

error:04066076:rsa routines:rsa_ossl_private_encrypt:unknown padding type:crypto/rsa/rsa_ossl.c:273:

问题原因与解决方法

核心问题:填充方案的适用场景错误

PKCS1_OAEP和PSS填充不能用于private_encrypt方法:

  • PKCS1_OAEP是专为公钥加密设计的安全填充方案
  • PSS是专为签名生成/验证设计的安全填充方案

private_encrypt仅支持传统PKCS1填充,若要使用安全填充方案,需根据实际场景选用对应API。

修正方案1:公钥加密搭配PKCS1_OAEP填充

常规加密场景下,应使用公钥加密、私钥解密,修改代码如下:

use openssl::{rsa::{Rsa, Padding}, symm::Cipher};
use bincode;

fn main() {
    let rsa = Rsa::generate(512).unwrap();
    let password = "password";
    let source = "hello paul".to_string();
    let data = bincode::serialize(&source).unwrap();
    let private = rsa.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), password.as_bytes()).unwrap();

    // 改用公钥执行加密
    let public_key_pem = rsa.public_key_to_pem().unwrap();
    let pub_key = Rsa::public_key_from_pem(&public_key_pem).unwrap();

    let mut enc_data = vec![0; pub_key.size() as usize];
    match pub_key.public_encrypt(&data, &mut enc_data, Padding::PKCS1_OAEP) {
        Ok(_) => println!("加密成功"),
        Err(e) => {
            println!("{e}");
            return;
        }
    }
}

修正方案2:PSS填充搭配签名API(私钥场景)

若需求是用私钥生成签名,需使用sign方法而非private_encrypt:

use openssl::{rsa::{Rsa, Padding}, symm::Cipher, hash::MessageDigest};
use bincode;

fn main() {
    let rsa = Rsa::generate(512).unwrap();
    let password = "password";
    let source = "hello paul".to_string();
    let data = bincode::serialize(&source).unwrap();
    let private = rsa.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), password.as_bytes()).unwrap();

    let private_key = Rsa::private_key_from_pem_passphrase(&private, password.as_bytes()).unwrap();

    // 使用PSS填充生成签名
    let mut sig = vec![0; private_key.size() as usize];
    let sig_len = private_key.sign(MessageDigest::sha256(), &data, &mut sig, Padding::PKCS1_PSS).unwrap();
    sig.truncate(sig_len);
    println!("签名成功,签名长度:{}", sig_len);
}

额外说明

  • 无需更换Cipher,Cipher仅用于加密私钥PEM文件,与RSA加密/签名的填充方案无关。
  • 你的openssl依赖版本(0.10.44)完全支持PKCS1_OAEP和PSS填充,问题出在API使用错误而非功能未实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 06:40:20