zero4rs 2.0.0

zero4rs is a powerful, pragmatic, and extremely fast web framework for Rust
Documentation
use aes_gcm::{
    aead::{Aead, AeadCore, KeyInit, OsRng},
    Aes256Gcm, Key, Nonce,
};

use crate::core::error2::Result;

// 密钥(Key):
// -- 密钥是用于加密和解密的秘密值。
// -- 只有知道密钥的人能够对加密的信息进行解密。
// -- 密钥通常是一个比特序列,其长度与加密算法相关。
// 初始化向量(IV):
// -- 初始化向量是一个随机或者伪随机生成的固定长度的比特序列。
// -- 在同一个密钥下,使用不同的初始化向量可以产生不同的加密结果。
// -- 初始化向量的主要作用是在相同的密钥下,使得相同的明文加密后不会得到相同的密文。
// -- 它对于一些块加密算法(如 AES)是必需的。
// Key 和 IV 的长度匹配:
// -- 确保你传递给 encrypt 函数的 key 和 iv 的长度与密码算法的要求匹配。
// -- 例如,AES 的块大小为 128 位,因此对应的 key 和 iv 长度通常是 128 位(16 字节)。
// 数据长度的处理: 确保 plaintext 的长度是块长度的整数倍。
// -- 可以在进行加密之前,将数据进行填充,以满足块大小的要求。
// -- 通常使用的填充方案包括 PKCS7 填充。

// https://backendengineer.io/aes-encryption-rust/
// 密钥长度   密钥大小            加密轮数
// AES-128   16字符(128位)      10轮
// AES-192   24字符(192位)      12轮
// AES-256   32字符(256位)      14轮
#[allow(deprecated)]
pub fn aes_256_encrypt(key_str_32: &str, plaintext: &str) -> Result<String> {
    let key = Key::<Aes256Gcm>::from_slice(key_str_32.as_bytes());
    let nonce = Aes256Gcm::generate_nonce(&mut OsRng);

    let cipher = Aes256Gcm::new(key);

    let ciphered_data = cipher
        .encrypt(&nonce, plaintext.as_bytes())
        .expect("failed to encrypt");

    // combining nonce and encrypted data together
    // for storage purpose
    let mut encrypted_data: Vec<u8> = nonce.to_vec();
    encrypted_data.extend_from_slice(&ciphered_data);

    Ok(hex::encode(encrypted_data))
}

#[allow(deprecated)]
pub fn aes_256_decrypt(key_str: &str, encrypted_data: &str) -> Result<String> {
    let encrypted_data = hex::decode(encrypted_data).map_err(|e| anyhow::anyhow!(e))?;

    let key = Key::<Aes256Gcm>::from_slice(key_str.as_bytes());
    let (nonce_arr, ciphered_data) = encrypted_data.split_at(12);
    let nonce = Nonce::from_slice(nonce_arr);
    let cipher = Aes256Gcm::new(key);

    let plaintext = cipher
        .decrypt(nonce, ciphered_data)
        .map_err(|e| anyhow::anyhow!(e))?;

    let l = String::from_utf8(plaintext).map_err(|e| anyhow::anyhow!(e))?;

    Ok(l)
}