diff --git a/src/infra/encryption/algorithm/aes.rs b/src/infra/encryption/algorithm/aes.rs index 201e7c4122645a5c7092d1f908f86fa82e19b3a2..641669f815e71f3a7ff2903e75e87e6d0ca66ed1 100644 --- a/src/infra/encryption/algorithm/aes.rs +++ b/src/infra/encryption/algorithm/aes.rs @@ -22,8 +22,11 @@ use aes_gcm_siv::{ }; use generic_array::GenericArray; use rand::{thread_rng, Rng}; +use crate::util::error; +use crate::util::error::Result; pub const NONCE_LENGTH: usize = 12; +pub const KEY_LENGTH: usize = 32; #[derive(Default)] pub struct Aes256GcmEncryptor {} @@ -43,7 +46,10 @@ impl Encryptor for Aes256GcmEncryptor { Algorithm::Aes256GSM } - fn encrypt(&self, key: Vec, content: Vec) -> crate::util::error::Result> { + fn encrypt(&self, key: Vec, content: Vec) -> Result> { + if key.len() != KEY_LENGTH { + return Err(Error::EncodeError("key size not matched".to_string())) + } let cipher = Aes256GcmSiv::new(GenericArray::from_slice(&key)); let random = self.generate_nonce_bytes(); let nonce = GenericArray::from_slice(&random); @@ -56,12 +62,15 @@ impl Encryptor for Aes256GcmEncryptor { Ok(encrypted) } - fn decrypt(&self, key: Vec, content: Vec) -> crate::util::error::Result> { - if key.len() <= NONCE_LENGTH { + fn decrypt(&self, key: Vec, content: Vec) -> Result> { + if content.len() <= NONCE_LENGTH { return Err(Error::EncodeError( - "failed to decode cluster key due to incorrect length".to_string(), + "failed to decode due to incorrect length".to_string(), )); } + if key.len() != KEY_LENGTH { + return Err(Error::EncodeError("key size not matched".to_string())) + } let cipher = Aes256GcmSiv::new(GenericArray::from_slice(&key)); let nonce = GenericArray::from_slice(&content[..NONCE_LENGTH]); let decrypted = cipher @@ -70,3 +79,99 @@ impl Encryptor for Aes256GcmEncryptor { Ok(decrypted) } } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_generate_keys() { + let aes = Aes256GcmEncryptor::default(); + let key_1 = aes.generate_key(); + let key_2 = aes.generate_key(); + assert_ne!(key_1, key_2); + assert_eq!(32, key_2.len()); + assert_eq!(32, key_1.len()); + } + + #[test] + fn test_generate_nonce() { + let aes = Aes256GcmEncryptor::default(); + let nonce_1 = aes.generate_nonce_bytes(); + let nonce_2 = aes.generate_nonce_bytes(); + assert_ne!(nonce_1, nonce_2); + assert_eq!(NONCE_LENGTH, nonce_1.len()); + assert_eq!(NONCE_LENGTH, nonce_2.len()); + } + + #[test] + fn test_encrypt_decrypt_successful_with_one_key() { + let aes = Aes256GcmEncryptor::default(); + let key1 = aes.generate_key(); + let content = "fake_content".as_bytes(); + let encoded_1 = aes.encrypt(key1.clone(), content.to_vec()).expect("encode should be successful"); + let encoded_2 = aes.encrypt(key1.clone(), content.to_vec()).expect("encode should be successful"); + assert_ne!(encoded_1, encoded_2); + assert_eq!(encoded_1.len(), encoded_1.len()); + assert_ne!(encoded_1, content); + assert_ne!(encoded_2, content); + let decode_1 = aes.decrypt(key1.clone(), encoded_1).expect("decode should be successful"); + let decode_2 = aes.decrypt(key1.clone(), encoded_2).expect("decode should be successful"); + assert_eq!(content, decode_1); + assert_eq!(content, decode_2); + } + + #[test] + fn test_encrypt_decrypt_successful_with_different_keys() { + let aes = Aes256GcmEncryptor::default(); + let key1 = aes.generate_key(); + let key2 = aes.generate_key(); + let content = "fake_content".as_bytes(); + let encoded_1 = aes.encrypt(key1.clone(), content.to_vec()).expect("encode should be successful"); + let encoded_2 = aes.encrypt(key2.clone(), content.to_vec()).expect("encode should be successful"); + assert_ne!(encoded_1, encoded_2); + assert_eq!(encoded_1.len(), encoded_1.len()); + assert_ne!(encoded_1, content); + assert_ne!(encoded_2, content); + let decode_1 = aes.decrypt(key1.clone(), encoded_1).expect("decode should be successful"); + let decode_2 = aes.decrypt(key2.clone(), encoded_2).expect("decode should be successful"); + assert_eq!(content, decode_1); + assert_eq!(content, decode_2); + } + + #[test] + fn test_encrypt_decrypt_different_content_successful_one_key() { + let aes = Aes256GcmEncryptor::default(); + let key1 = aes.generate_key(); + let content_1 = "fake_content1".as_bytes(); + let content_2 = "fake_content 2".as_bytes(); + let encoded_1 = aes.encrypt(key1.clone(), content_1.to_vec()).expect("encode should be successful"); + let encoded_2 = aes.encrypt(key1.clone(), content_2.to_vec()).expect("encode should be successful"); + assert_ne!(encoded_1, encoded_2); + assert_ne!(encoded_1, content_1); + assert_ne!(encoded_2, content_2); + let decode_1 = aes.decrypt(key1.clone(), encoded_1).expect("decode should be successful"); + let decode_2 = aes.decrypt(key1.clone(), encoded_2).expect("decode should be successful"); + assert_eq!(content_1, decode_1); + assert_eq!(content_2, decode_2); + } + + #[test] + fn test_decrypt_with_invalid_content() { + let aes = Aes256GcmEncryptor::default(); + let key1 = aes.generate_key(); + let encoded = "123456789abc".as_bytes(); + let invalid = "invalid_encoded_content_although_long_enough".as_bytes(); + let _ = aes.decrypt(key1.clone(), vec![]).expect_err("decode should fail due to content not long enough"); + let _ = aes.decrypt(key1.clone(), encoded.to_vec()).expect_err("decode should fail due to content not long enough"); + let _ = aes.decrypt(key1.clone(), invalid.to_vec()).expect_err("decode should fail due to content invalid"); + } + + #[test] + fn test_encrypt_decrypt_with_invalid_key_size() { + let aes = Aes256GcmEncryptor::default(); + let invalid_key = "invalid_key".as_bytes(); + let _ = aes.encrypt(invalid_key.to_vec(), vec![]).expect_err("encode should fail due to key size invalid"); + let _ = aes.decrypt(invalid_key.to_vec(), vec![]).expect_err("decode should fail due to key size invalid"); + } +} \ No newline at end of file