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

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版本:当前使用的openssl 0.10版本对OpenSSL 3.x的跨平台支持可能存在瑕疵,尝试升级到openssl 0.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:40:26