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

Rust实现CryptoJS AES ECB解密遇错误,请求技术支持

解决Rust中AES-ECB解密的UnpadError问题

问题背景

需要将JavaScript中的AES-ECB解密逻辑迁移到Rust,JavaScript示例代码运行正常,能正确完成加密解密流程:

const CryptoJS = require('crypto-js');

const key = "KeyIs16CharsLong";
const value = "Hello, Rust!";

const keyParsed = CryptoJS.enc.Utf8.parse(key);

// 加密
const encrypted = CryptoJS.AES.encrypt(value, keyParsed, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}).toString();

console.log(key); // 'KeyIs16CharsLong'
console.log(encrypted); // 'nFWwLNMi2toxug1hDb/HGg=='

// 解密
const decrypted = CryptoJS.AES.decrypt(encrypted, keyParsed, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8);

console.log("Decrypted:", decrypted); // Decrypted: Hello, Rust!

但在Rust中实现解密时,触发了UnpadError,原尝试代码如下:

use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyInit};
use base64::Engine;
use base64::engine::general_purpose; 

type Aes128EcbDec = ecb::Decryptor<aes::Aes128>;

fn test_decryption() {
    let key = "KeyIs16CharsLong";
    let plaintext = "nFWwLNMi2toxug1hDb/HGg==";

    // Decode key and adjust to 16 bytes
    let mut key_vec = general_purpose::STANDARD.decode(key).expect("Invalid Base64 key");
    key_vec.resize(16, 0); // Pad with zeros if the decoded key is too short
    let key: [u8; 16] = key_vec.try_into().expect("Key must be 16 bytes for AES-128");

    // Convert ciphertext from hex to bytes
    let mut ciphertext = general_purpose::STANDARD.decode(plaintext).expect("Invalid Base64 ciphertext");

    let pt = Aes128EcbDec::new(&key.into())
        .decrypt_padded_mut::<Pkcs7>(&mut ciphertext)
        .unwrap();

    // Convert decrypted plaintext to a string
    let decrypted_plaintext = String::from_utf8(pt.to_vec()).expect("Decryption produced invalid UTF-8");
    println!("Decrypted plaintext: {}", decrypted_plaintext);
}

运行时错误信息:

thread 'main' panicked at src/main.rs:30:10:
called `Result::unwrap()` on an `Err` value: UnpadError

错误原因

核心问题是密钥处理逻辑完全错误:

  • JavaScript中CryptoJS.enc.Utf8.parse(key)是直接将密钥字符串转换为UTF-8字节数组作为AES密钥
  • 原Rust代码错误地对密钥字符串执行了Base64解码,导致生成的密钥与JS侧加密使用的密钥完全不符,解密时无法还原正确明文,最终触发PKCS7解填充失败

修正后的代码

调整密钥处理逻辑,直接将字符串转为UTF-8字节数组即可:

use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, KeyInit};
use base64::Engine;
use base64::engine::general_purpose; 

type Aes128EcbDec = ecb::Decryptor<aes::Aes128>;

fn test_decryption() {
    let key_str = "KeyIs16CharsLong";
    let ciphertext_b64 = "nFWwLNMi2toxug1hDb/HGg==";

    // 直接将密钥字符串转为UTF-8字节数组,无需Base64解码
    let key_bytes = key_str.as_bytes();
    // 确认密钥长度为16字节(AES-128要求),原字符串刚好16字符,UTF-8下每个字符占1字节
    let key: [u8; 16] = key_bytes.try_into().expect("Key must be 16 bytes for AES-128");

    // 解码Base64格式的密文
    let mut ciphertext = general_purpose::STANDARD.decode(ciphertext_b64).expect("Invalid Base64 ciphertext");

    // 解密并自动处理PKCS7解填充
    let plaintext_bytes = Aes128EcbDec::new(&key.into())
        .decrypt_padded_mut::<Pkcs7>(&mut ciphertext)
        .expect("Decryption or unpadding failed");

    // 将明文字节转为UTF-8字符串
    let decrypted_plaintext = String::from_utf8(plaintext_bytes.to_vec()).expect("Invalid UTF-8 in decrypted plaintext");
    println!("Decrypted plaintext: {}", decrypted_plaintext);
}

运行结果

修正后代码运行会输出:

Decrypted plaintext: Hello, Rust!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 22:30:53