首页 > 解决方案 > 即使数据正确,AES-GCM 256 解密也会失败

问题描述

我有一个给定的加密消息(已解密,它是“加密的秘密消息”),我正在尝试从 AES-GCM 256 加密的消息中检索这个原始字符串。我使用aes-gcm板条箱来执行此操作:

use aes_gcm::Aes256Gcm;
use aead::{Aead, NewAead, generic_array::GenericArray};

fn main() {
    let key_bytes = hex::decode("ce265dbc38bb25ef29fade77a4b88fe07b6063215f6526a4623cf810a3d611c9").unwrap();
    let nonce_bytes = hex::decode("ce77357fe7b2401400408f44").unwrap();
    let ciphertext_bytes = hex::decode("fd77fae68fa27ea00afbe474f4fcd47248a19b3cbf2a6d7e").unwrap();

    let key = GenericArray::clone_from_slice(key_bytes.as_slice());
    let nonce = GenericArray::from_slice(nonce_bytes.as_slice());

    let cipher = Aes256Gcm::new(key);
    let plaintext = cipher.decrypt(nonce, ciphertext_bytes.as_slice()).unwrap(); // panic on a decryption failure

    println!("{:?}", plaintext);
}

这是dependencies我的 Cargo.toml 的部分:

[dependencies]
aes-gcm = "0.5.0"
aead = "0.2.0"
hex = "0.4.2"

问题是程序总是在第unwrap13 行调用时出现恐慌,即使加密的消息、密钥和随机数都很好:

thread 'main' panicked at 'called Result::unwrap() on an Err value: Error', src\main.rs:13:21

看起来这是加密消息无效,加密消息,密钥或随机数无效的错误,但它不是。我写了一个 Python 程序,它做同样的事情并且它可以工作;输出确实encrypted secret message

from Crypto.Cipher import AES

key = bytes.fromhex("ce265dbc38bb25ef29fade77a4b88fe07b6063215f6526a4623cf810a3d611c9")

nonce = bytes.fromhex("ce77357fe7b2401400408f44")
cipher_text = bytes.fromhex("fd77fae68fa27ea00afbe474f4fcd47248a19b3cbf2a6d7e")

cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
plaintext = cipher.decrypt(cipher_text)

print(plaintext.decode("utf-8"))

我希望能够在 Rust 中解密这些加密消息,而不是在 Python 中。我不知道为什么我会得到一个错误。我错过了什么?

标签: encryptionrustcryptographyaesaes-gcm

解决方案


encrypt,强调我的:

默认实现采用后缀标签(ala AES-GCM、AES-GCM-SIV、ChaCha20Poly1305)。不使用后缀标签的 Aead 实现将需要覆盖它以正确组合密文消息。

既然你说你有标签:

我也有此加密消息的关联标签

您可以遵循相同的模式:

use aead::{generic_array::GenericArray, Aead, NewAead};
use aes_gcm::Aes256Gcm;

fn main() {
    let key_hex = "ce265dbc38bb25ef29fade77a4b88fe07b6063215f6526a4623cf810a3d611c9";
    let nonce_hex = "ce77357fe7b2401400408f44";
    let ciphertext_hex = "fd77fae68fa27ea00afbe474f4fcd47248a19b3cbf2a6d7e";

    // Append the tag data to the encrypted data
    let tag_hex = "2ef2a9d27909df90bcb45606067148a6";
    let ciphertext_and_tag_hex = format!("{}{}", ciphertext_hex, tag_hex);
    let ciphertext_bytes = hex::decode(ciphertext_and_tag_hex).unwrap();

    let key_bytes = hex::decode(key_hex).unwrap();
    let nonce_bytes = hex::decode(nonce_hex).unwrap();

    let key = GenericArray::clone_from_slice(&key_bytes);
    let nonce = GenericArray::from_slice(&nonce_bytes);

    let cipher = Aes256Gcm::new(key);

    let plaintext = cipher.decrypt(nonce, &*ciphertext_bytes).unwrap();
    println!("{}", String::from_utf8_lossy(&plaintext));
}

您还可以研究该decrypt_in_place_detached方法,该方法更复杂但允许单独指定标签。


推荐阅读