Windows下Rust程序解密AES密钥失败问题求助
Rust UDP加解密程序跨平台解密失败问题
我是Rust新手,编写了一套UDP加解密程序,在Ubuntu系统上能正常接收并解密Android应用发送的消息,但在Windows系统运行时触发OAEP解码错误。以下是相关代码、报错信息及当前排查情况,求解决思路:
src/main.rs
use openssl::{ pkey::PKey, rsa::{Padding, Rsa}, symm::{Cipher, Crypter, Mode}, encrypt::Decrypter, }; use rpassword::read_password_from_tty; use std::net::SocketAddr; use tokio::{ net::UdpSocket, }; #[tokio::main] async fn main() { // Load the private key println!("Enter RSA private key passphrase:"); let passphrase = read_password_from_tty(Some("Passphrase: ")).expect("Failed to read passphrase"); let private_key = include_bytes!("private_key_enc2.pem"); let rsa = Rsa::private_key_from_pem_passphrase(private_key, passphrase.as_bytes()).expect("Failed to load private key"); let pkey = PKey::from_rsa(rsa).expect("Failed to create PKey from RSA"); // Start the UDP server let addr: SocketAddr = "0.0.0.0:12345".parse().expect("Invalid socket address"); let socket = UdpSocket::bind(&addr) .await .expect("Failed to bind to the socket"); println!("Server listening on {}", addr); let mut buf = [0; 65535]; // A buffer large enough for UDP packet loop { // Receive the encrypted message let (len, _src) = socket.recv_from(&mut buf).await.expect("Failed to read from socket"); let data = &buf[..len]; // Extract the RSA-encrypted AES key, IV, and encrypted message by their lengths // encrypted AES key length = 2048 bytes (16384 bits) let (encrypted_aes_key, rest) = data.split_at(2048); // IV length = 16 bytes for AES-256-CBC let (iv, encrypted_message) = rest.split_at(16); // Decrypt the AES key let mut decrypter = Decrypter::new(&pkey).expect("Failed to create decrypter"); decrypter.set_rsa_padding(Padding::PKCS1_OAEP).expect("Failed to set padding"); decrypter.set_rsa_oaep_md(openssl::hash::MessageDigest::sha256()).expect("Failed to set OAEP digest"); decrypter.set_rsa_mgf1_md(openssl::hash::MessageDigest::sha256()).expect("Failed to set MGF1 digest"); let mut aes_key = vec![0; pkey.size()]; let aes_key_len = decrypter.decrypt(encrypted_aes_key, &mut aes_key).expect("Failed to decrypt AES key"); aes_key.truncate(aes_key_len); // Decrypt the message using AES-256-CBC let cipher = Cipher::aes_256_cbc(); let mut crypter = Crypter::new(cipher, Mode::Decrypt, &aes_key, Some(iv)).expect("Failed to create AES crypter"); let mut plaintext = vec![0; encrypted_message.len() + cipher.block_size()]; let count = crypter.update(encrypted_message, &mut plaintext).expect("Failed to decrypt message"); let rest = crypter.finalize(&mut plaintext[count..]).expect("Failed to finalize decryption"); plaintext.truncate(count + rest); // Print the decrypted message let message = String::from_utf8(plaintext).expect("Failed to parse plaintext as UTF-8"); println!("Received and decrypted message: {}", message); } }
Cargo.toml
... [dependencies] openssl = "0.10" tokio = { version = "1", features = ["full"] } rpassword = "5.0.1"
Windows运行报错
thread 'main' panicked at src\main.rs:36:14: Failed to decrypt AES key: ErrorStack([Error { code: 33554553, library: "rsa routines", function: "RSA_padding_check_PKCS1_OAEP_mgf1", reason: "oaep decoding error", file: "crypto\\rsa\\rsa_oaep.c", line: 314 }, Error { code: 33554546, library: "rsa routines", function: "rsa_ossl_private_decrypt", reason: "padding check failed", file: "crypto\\rsa\\rsa_ossl.c", line: 499 }])
已通过choco安装OpenSSL 3.1.1并配置OPENSSL_DIR、OPENSSL_INCLUDE_DIR、OPENSSL_LIB_DIR环境变量,编译无报错。怀疑问题源于Windows(OpenSSL 3.1.1)与Ubuntu(OpenSSL 3.0.2)的版本差异,尝试交叉编译未成功。
解决思路建议
- 统一OpenSSL版本:在Windows上降级到OpenSSL 3.0.2,与Ubuntu端保持版本一致,规避版本间OAEP实现的细节差异。可从OpenSSL官网下载对应版本二进制包,替换choco安装版本后重新配置环境变量、编译程序。
- 校验UDP接收数据一致性:在Windows端打印
encrypted_aes_key的前若干字节,与Ubuntu端接收的对应数据对比,确认UDP传输过程中没有出现数据截断、字节序差异或编码问题。 - 升级openssl crate版本:当前使用的
openssl0.10版本对OpenSSL 3.x的跨平台支持可能存在瑕疵,尝试升级到openssl0.10.x系列的最新补丁版,或迁移至0.11+稳定版(注意适配API变化),更新Cargo.lock后重新编译。 - 检查私钥文件格式:Windows与Linux的换行符(CRLF vs LF)可能导致私钥解析异常,将
private_key_enc2.pem转换为LF换行格式后重新测试,同时对比两端加载私钥后的pkey.size()值,确认密钥加载正确。 - 启用OpenSSL调试日志:在Windows上设置环境变量
OPENSSL_DEBUG_LEVEL=3,运行程序查看详细解密日志,定位OAEP解码失败的具体触发点。
内容的提问来源于stack exchange,提问作者Pedro Lobito
相关产品推荐
相关产品推荐

