如何使用AAD和Rust的AES-GCM解密?

yjghlzjz  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(145)

AES-GCM的文档仅演示了无AAD的解密。
我需要使用这个附加的关联数据,因为我的密文已经用它加密了(在C和JavaScript实现中)。
在NodeJS/JavaScript中,我这样做:

const decipher = crypto.createDecipheriv('aes-256-gcm', km, iv);
decipher.setAAD(aad);
decipher.setAuthTag(tag);
const plaintext = decipher.update(ciphertext);
return Buffer.concat([plaintext, decipher.final()]);

字符串
我在各种Rust对象上尝试了VSCode自动完成,但还没有发现任何提到AAD的函数。

  • 有没有一种方法可以搜索包含字符串'AAD'的Rust函数,这比Google搜索更好?
  • 如何解密使用AAD的密文?
8cdiaqws

8cdiaqws1#

在移植NodeJS代码时,需要记住两件事:

  • 在NodeJS代码中,密文和标签是分开处理的,在Rust代码中,它们是连接处理的(密文|连接可以在加密期间在NodeJS代码中显式地完成,或者在解密期间在Rust代码中显式地完成。
  • AAD将与密文/标记串联在Payload结构中一起传递(如注解中所述)。

示例(Rust代码中密文和标签的连接):

use aes_gcm::{aead::{Aead, KeyInit, Payload}, Aes256Gcm, Nonce, Key}; 
use base64::{engine::general_purpose, Engine as _};
use std::str;

fn main() { 

    // Input data (e.g. Base64 encoded)
    let key_b64 = "gCOxqU/5JIUrEp5bZ+BSv0pqkV7fpC0sAtRLD6/alSc=";
    let nonce_b64 = "zGj7byavu/FF7XlC"; 
    let aad_b64 = "c29tZSBhZGRpdGlvbmFsIGRhdGEgdG8gYXV0aGVudGljYXRl"; // Base64 encoding of: "some additional data to authenticate"
    let ciphertext_b64 = "cJ/gL3Q+YDCbS69dkWWz3TBzmrxZiZ9arcxjMIgeoLZl4GQcYAgAvDxttg==";
    let tag_b64 = "4xjofRMg3fuUvpUTiKNquA==";
  
    // Base64 decode ciphertext and tag, concatenate both: ciphertext|tag 
    let ciphertext = general_purpose::STANDARD.decode(&ciphertext_b64).unwrap();
    let tag = general_purpose::STANDARD.decode(&tag_b64).unwrap();
    let ciphertext_tag = [ciphertext, tag].concat();

    // Base64 decode AAD
    let aad = general_purpose::STANDARD.decode(&aad_b64).unwrap();
    //let aad = String::from("some additional data to authenticate").into_bytes(); // alternatively, if AAD are simply a string
    
    // Wrap ciphertext|tag and AAD in Payload struct
    let payload = Payload {
        msg: &ciphertext_tag[..],
        aad: &aad[..],
    };

    // Base64 decode key and nonce, import both
    let nonce = general_purpose::STANDARD.decode(&nonce_b64).unwrap();
    let key = general_purpose::STANDARD.decode(&key_b64).unwrap();
    let nonce = Nonce::from_slice(&nonce[..]);  
    let key = Key::<Aes256Gcm>::from_slice(&key[..]);

    // Decrypt
    let cipher = Aes256Gcm::new(&key);
    match cipher.decrypt(&nonce, payload) {
        Ok(decrypted) => println!("Decrypted data: {}", str::from_utf8(&decrypted).unwrap()), // Decrypted data: The quick brown fox jumps over the lazy dog
        Err(e) => eprintln!("Decryption error: {}", e),
    }
}

字符串
发布的NodeJS代码使用以下输入给出了相同的结果:

var km = Buffer.from('gCOxqU/5JIUrEp5bZ+BSv0pqkV7fpC0sAtRLD6/alSc=', 'base64');
var iv = Buffer.from('zGj7byavu/FF7XlC', 'base64');
var aad = Buffer.from('c29tZSBhZGRpdGlvbmFsIGRhdGEgdG8gYXV0aGVudGljYXRl', 'base64');
var ciphertext = Buffer.from('cJ/gL3Q+YDCbS69dkWWz3TBzmrxZiZ9arcxjMIgeoLZl4GQcYAgAvDxttg==', 'base64');
var tag = Buffer.from('4xjofRMg3fuUvpUTiKNquA==', 'base64');

相关问题