use aes_gcm::{
Aes256Gcm, Key, Nonce,
aead::{Aead, KeyInit, OsRng, rand_core::RngCore},
};
use base64::{Engine as _, engine::general_purpose};
pub fn encrypt_string(plain_text: &str, secret_key: &str) -> Result<String, String> {
let mut key_bytes = [0u8; 32];
let secret_bytes = secret_key.as_bytes();
let key_len = std::cmp::min(secret_bytes.len(), 32);
key_bytes[..key_len].copy_from_slice(&secret_bytes[..key_len]);
let key = Key::<Aes256Gcm>::from_slice(&key_bytes);
let cipher = Aes256Gcm::new(key);
let mut nonce_bytes = [0u8; 12];
OsRng.fill_bytes(&mut nonce_bytes);
let nonce = Nonce::from_slice(&nonce_bytes);
let ciphertext = cipher
.encrypt(nonce, plain_text.as_bytes())
.map_err(|e| format!("Encryption failed: {e}"))?;
let mut combined = nonce_bytes.to_vec();
combined.extend_from_slice(&ciphertext);
Ok(general_purpose::STANDARD.encode(combined))
}
pub fn decrypt_string(encrypt_text: &str, secret_key: &str) -> Result<String, String> {
let combined = general_purpose::STANDARD
.decode(encrypt_text)
.map_err(|_| "Base64 decode failed".to_string())?;
if combined.len() < 12 {
return Err("Invalid ciphertext length".to_string());
}
let (nonce_bytes, ciphertext) = combined.split_at(12);
let nonce = Nonce::from_slice(nonce_bytes);
let mut key_bytes = [0u8; 32];
let secret_bytes = secret_key.as_bytes();
let key_len = std::cmp::min(secret_bytes.len(), 32);
key_bytes[..key_len].copy_from_slice(&secret_bytes[..key_len]);
let key = Key::<Aes256Gcm>::from_slice(&key_bytes);
let cipher = Aes256Gcm::new(key);
let plaintext = cipher
.decrypt(nonce, ciphertext)
.map_err(|e| format!("Decryption failed: {e}"))?;
String::from_utf8(plaintext).map_err(|_| "UTF-8 conversion failed".to_string())
}