use crate::config::EncryptionConfig;
use aes::Aes128;
use block_modes::{BlockMode, Cbc};
use block_modes::block_padding::Pkcs7;
use crate::encryption::traits::{Encryption, Aes128CbcCipher};
type Aes128Cbc = Cbc<Aes128, Pkcs7>;
pub struct Aes128CbcEncryption {
key: Vec<u8>,
iv: Vec<u8>,
}
impl Encryption for Aes128CbcEncryption {
fn new() -> Self {
let cfg = EncryptionConfig::from_env().unwrap();
let key = hex::decode(cfg.key).unwrap();
let iv = hex::decode(cfg.iv).unwrap();
Self {
key,
iv,
}
}
fn encrypt(&self, bytes: &[u8]) -> Vec<u8> {
self.new_cipher().encrypt_vec(bytes)
}
#[allow(dead_code)]
fn encrypt_string(&self, text: &String) -> Vec<u8> {
self.encrypt(text.as_bytes())
}
fn decrypt(&self, cipher_bytes: &[u8]) -> String {
let decrypt_vec = self.new_cipher().decrypt_vec(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)
}
}
impl Aes128CbcCipher for Aes128CbcEncryption {
fn new_cipher(&self) -> Cbc<Aes128, Pkcs7> {
Aes128Cbc::new_from_slices(self.key.as_slice(), self.iv.as_slice()).unwrap()
}
}
#[cfg(test)]
mod test {
use crate::encryption::traits::Encryption;
use crate::encryption::Aes128CbcEncryption;
#[test]
fn test_aes128_cbc_encrypt() {
let enc = Aes128CbcEncryption::new();
let test_data = String::from("Hello world!");
let _encrypted_data = enc.encrypt_string(&test_data);
}
#[test]
fn test_aes128_cbc_decrypt() {
let enc = Aes128CbcEncryption::new();
let test_data = vec![27, 122, 76, 64, 49, 36, 174, 47, 181, 43, 237, 197, 52, 216, 47, 168];
let _decrypted_data = enc.decrypt_vec(test_data);
}
#[test]
fn test_aes128_cbc_encrypt_decrypt() {
let enc = Aes128CbcEncryption::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)
}
}