AES-GCM 密钥与 Nonce 的生成、编码与解码:完整教程与示例代码

文摘   2024-11-01 00:05   北京  

引言

在 AES-GCM(Galois/Counter Mode)加密算法中,密钥和 nonce 是确保加密过程安全性和唯一性的关键组成部分。本文将详细介绍如何生成 AES-GCM 密钥和 nonce,并将其转换为 Base64 编码的字符串,以便于传输和存储。同时,我们还将展示如何从 Base64 编码的字符串中还原密钥和 nonce。

1. 生成 AES-GCM 密钥和 Nonce

1.1 生成密钥

AES-GCM 使用 256 位(32 字节)的密钥。我们可以使用rand库生成一个随机的 256 位密钥。

1.2 生成 Nonce

AES-GCM 使用 96 位(12 字节)的 nonce。同样,我们可以使用rand库生成一个随机的 96 位 nonce。

2. 将密钥和 Nonce 转换为 Base64 编码

为了便于传输和存储,通常将密钥和 nonce 转换为 Base64 编码的字符串。Base64 编码将每 3 个字节的数据转换为 4 个字符。

3. 从 Base64 编码的字符串还原密钥和 Nonce

在接收到 Base64 编码的字符串后,我们可以将其解码为原始的字节数组,并还原为密钥和 nonce。

4. 完整示例代码

以下是一个完整的示例代码,展示了如何生成 AES-GCM 密钥和 nonce,并将其转换为 Base64 编码的字符串,以及如何从 Base64 编码的字符串中还原密钥和 nonce。

use aes_gcm::aead::generic_array::GenericArray;
use aes_gcm::aead::generic_array::typenum::{U12, U32};
use base64::{Engine as _, engine::general_purpose};
use rand::RngCore;
use rand::rngs::OsRng;

// 生成随机的 256 位密钥
fn generate_key() -> GenericArray<u8, U32> {
    let mut key = GenericArray::default();
    OsRng.fill_bytes(&mut key);
    key
}

// 生成随机的 96 位 nonce
fn generate_nonce() -> GenericArray<u8, U12> {
    let mut nonce = GenericArray::default();
    OsRng.fill_bytes(&mut nonce);
    nonce
}

// 将密钥转换为 Base64 编码的字符串
fn key_to_base64(key: &GenericArray<u8, U32>) -> String {
    general_purpose::STANDARD.encode(key)
}

// 将 nonce 转换为 Base64 编码的字符串
fn nonce_to_base64(nonce: &GenericArray<u8, U12>) -> String {
    general_purpose::STANDARD.encode(nonce)
}

// 从 Base64 编码的字符串还原密钥
fn base64_to_key(base64_str: &str) -> Result<GenericArray<u8, U32>, Box<dyn std::error::Error>> {
    let key_bytes = general_purpose::STANDARD.decode(base64_str)?;
    if key_bytes.len() != 32 {
        return Err("Invalid key length".into());
    }
    let key = GenericArray::clone_from_slice(&key_bytes);
    Ok(key)
}

// 从 Base64 编码的字符串还原 nonce
fn base64_to_nonce(base64_str: &str) -> Result<GenericArray<u8, U12>, Box<dyn std::error::Error>> {
    let nonce_bytes = general_purpose::STANDARD.decode(base64_str)?;
    if nonce_bytes.len() != 12 {
        return Err("Invalid nonce length".into());
    }
    let nonce = GenericArray::clone_from_slice(&nonce_bytes);
    Ok(nonce)
}

fn main() {
    // 生成密钥和 nonce
    let key = generate_key();
    let nonce = generate_nonce();

    // 将密钥和 nonce 转换为 Base64 编码的字符串
    let key_base64 = key_to_base64(&key);
    let nonce_base64 = nonce_to_base64(&nonce);

    println!("Key (Base64): {}", key_base64);
    println!("Nonce (Base64): {}", nonce_base64);

    // 从 Base64 编码的字符串还原密钥和 nonce
    match base64_to_key(&key_base64) {
        Ok(key) => println!("Key: {:?}", key),
        Err(e) => println!("Error: {}", e),
    }

    match base64_to_nonce(&nonce_base64) {
        Ok(nonce) => println!("Nonce: {:?}", nonce),
        Err(e) => println!("Error: {}", e),
    }
}

5. 详细步骤解释

5.1 生成密钥和 Nonce

  • 生成密钥:使用rand::RngCore生成一个随机的 256 位密钥。
  • 生成 Nonce:使用rand::RngCore生成一个随机的 96 位 nonce。

5.2 将密钥和 Nonce 转换为 Base64 编码

  • 密钥转换:使用base64::Engine将密钥字节数组转换为 Base64 编码的字符串。
  • Nonce 转换:使用base64::Engine将 nonce 字节数组转换为 Base64 编码的字符串。

5.3 从 Base64 编码的字符串还原密钥和 Nonce

  • 密钥还原:使用base64::Engine将 Base64 编码的字符串解码为字节数组,并转换为GenericArray<u8, U32>类型。
  • Nonce 还原:使用base64::Engine将 Base64 编码的字符串解码为字节数组,并转换为GenericArray<u8, U12>类型。

6. 总结

本文详细介绍了如何生成 AES-GCM 密钥和 nonce,并将其转换为 Base64 编码的字符串,以便于传输和存储。同时,我们还展示了如何从 Base64 编码的字符串中还原密钥和 nonce。通过这些步骤,你可以确保密钥和 nonce 的安全传输和正确使用。

参考文献

  1. AES-GCM - Wikipedia[1]
  2. Base64 - Wikipedia[2]
  3. Rust `rand` crate documentation[3]
  4. Rust `aes-gcm` crate documentation[4]

通过本文的学习,读者可以更好地理解 AES-GCM 中密钥和 nonce 的作用和使用方法,从而在实际应用中确保加密过程的安全性和唯一性。

参考资料

[1]

AES-GCM - Wikipedia:https://en.wikipedia.org/wiki/Galois/Counter_Mode

[2]

Base64 - Wikipedia:https://en.wikipedia.org/wiki/Base64

[3]

Rustrandcrate documentation:https://docs.rs/rand/latest/rand/

[4]

Rustaes-gcmcrate documentation:https://docs.rs/aes-gcm/latest/aes_gcm/


无论身在何处

有我不再孤单孤单

长按识别二维码关注我们




育儿之家 YEZJ
“Rust编程之道”,带你探索Rust语言之美,精进编程技艺,开启无限可能!🦀🦀🦀
 最新文章