use std::collections::HashMap;
use aes::Aes128;
use aes::cipher::{
BlockDecryptMut, KeyIvInit, block_padding::Pkcs7,
generic_array::GenericArray,
};
use base64::{Engine, engine::general_purpose::STANDARD as BASE64};
use cbc::Decryptor;
use serde_json;
use super::key_normalizer::KeyNormalizer;
use crate::{CRYPTO_LOGGER_DOMAIN, Error, debug_log, error_log};
type Aes128CbcDecryptor = Decryptor<Aes128>;
pub struct AesDecrypt;
impl AesDecrypt {
pub fn decrypt(
encrypted: &str,
key: &str,
iv: &str,
) -> Result<HashMap<String, String>, Error> {
debug_log!(
CRYPTO_LOGGER_DOMAIN,
"Starting AES decryption for Base64 string"
);
let decoded = BASE64.decode(encrypted).map_err(|e| {
error_log!(
CRYPTO_LOGGER_DOMAIN,
"Failed to decode Base64 string: {}",
e
);
Error::Base64DecodeError(e)
})?;
let key = KeyNormalizer::normalize_from_str(key)?;
let iv_bytes = KeyNormalizer::normalize_from_str(iv)?;
let iv = GenericArray::from_slice(&iv_bytes);
let ciphertext = &decoded;
let cipher =
Aes128CbcDecryptor::new(GenericArray::from_slice(&key), iv);
let mut buffer = ciphertext.to_vec();
let decrypted = cipher
.decrypt_padded_mut::<Pkcs7>(&mut buffer)
.map_err(|e| {
error_log!(CRYPTO_LOGGER_DOMAIN, "Decryption failed: {}", e);
Error::DecryptionError(e.to_string())
})?;
let dict: HashMap<String, String> = serde_json::from_slice(decrypted)
.map_err(|e| {
error_log!(
CRYPTO_LOGGER_DOMAIN,
"Failed to deserialize JSON to dictionary: {}",
e
);
Error::JsonError(e)
})?;
debug_log!(
CRYPTO_LOGGER_DOMAIN,
"Decryption successful, restored dictionary"
);
Ok(dict)
}
}