use crate::config::EncryptionConfig;
use crate::encryption::traits::{Encryption};
use aes_gcm_siv::Aes256GcmSiv;
use aes_gcm_siv::aead::{Aead, NewAead, generic_array::GenericArray};
use crate::utils::Salt;
const NONCE_SIZE: u8 = 12;
pub struct AesGcmSivEncryption {
cipher: Aes256GcmSiv
}
impl Encryption for AesGcmSivEncryption {
fn new() -> Self {
let cfg = EncryptionConfig::from_env().unwrap();
let key = GenericArray::from_slice(
cfg.key.as_bytes()
);
let cipher = Aes256GcmSiv::new(key);
Self {
cipher
}
}
fn encrypt(&self, bytes: &[u8]) -> Vec<u8> {
let nonce_string = Salt::generate(NONCE_SIZE as usize);
let nonce = GenericArray::from_slice(nonce_string.as_bytes());
let cipher_text = self.cipher.encrypt(nonce, bytes).unwrap();
[nonce_string.as_bytes().to_vec(), cipher_text].concat()
}
#[allow(dead_code)]
fn encrypt_string(&self, text: &String) -> Vec<u8> {
self.encrypt(text.as_bytes())
}
fn decrypt(&self, bytes: &[u8]) -> String {
if bytes.get(12).is_none() {
return String::from("")
}
let (nonce_bytes, cipher_bytes) = bytes.split_at(12);
let nonce = GenericArray::from_slice(nonce_bytes);
let decrypt_vec = self.cipher.decrypt(nonce, cipher_bytes).unwrap();
String::from_utf8(decrypt_vec).unwrap_or_default()
}
#[allow(dead_code)]
fn decrypt_vec(&self, cipher_vector: Vec<u8>) -> String {
let cipher_bytes = cipher_vector.as_slice();
self.decrypt(cipher_bytes)
}
}
#[cfg(test)]
mod test {
use crate::encryption::traits::Encryption;
use crate::encryption::AesGcmSivEncryption;
#[test]
fn test_aes_gcm_siv_encrypt_decrypt() {
let enc = AesGcmSivEncryption::new();
let test_data = String::from("Hello world!");
let encrypted_data = enc.encrypt_string(&test_data);
let decrypted_data = enc.decrypt_vec(encrypted_data);
assert_eq!(test_data, decrypted_data)
}
}