use base64::{Engine};
use base64::engine::general_purpose::STANDARD;
use crypto::{aes, symmetriccipher};
use crypto::aes::KeySize::KeySize256;
use crypto::blockmodes::PkcsPadding;
use crypto::buffer::{BufferResult, ReadBuffer, RefReadBuffer, RefWriteBuffer, WriteBuffer};
use rand::random;
pub fn aes256_cbc_encrypt(
data: &[u8],
key: &str,
) -> String {
let key = string_to_fixed_array_32(key);
let mut iv = random::<[u8; 16]>(); let output = encrypt(data, &key, &mut iv);
let mut result = iv.to_vec();
result.extend(&output.expect("Failed to encrypt data"));
STANDARD.encode(&result) }
fn encrypt(data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
let mut encryptor = aes::cbc_encryptor(KeySize256, key, iv, PkcsPadding);
let mut final_result = Vec::<u8>::new();
let mut read_buffer = RefReadBuffer::new(data);
let mut buffer = [0; 4096];
let mut write_buffer = RefWriteBuffer::new(&mut buffer);
loop {
let result = encryptor.encrypt(&mut read_buffer, &mut write_buffer, true)?;
final_result.extend(write_buffer.take_read_buffer().take_remaining().iter().map(|&i| i));
match result {
BufferResult::BufferUnderflow => break,
BufferResult::BufferOverflow => { }
}
}
Ok(final_result)
}
pub fn aes256_cbc_decrypt(
data: &str,
key: &str
) -> String {
let data = STANDARD.decode(data).expect("Failed to decode Base64");
let key = string_to_fixed_array_32(key);
let (iv, data) = data.split_at(16);
let output = decrypt(data, &key, iv).expect("Failed to decrypt data");
String::from_utf8(output).expect("Failed to convert to string")
}
fn decrypt(encrypted_data: &[u8], key: &[u8], iv: &[u8]) -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
let mut decryptor = aes::cbc_decryptor(KeySize256, key, iv, PkcsPadding);
let mut final_result = Vec::<u8>::new();
let mut read_buffer = RefReadBuffer::new(encrypted_data);
let mut buffer = [0; 4096];
let mut write_buffer = RefWriteBuffer::new(&mut buffer);
loop {
let result = decryptor.decrypt(&mut read_buffer, &mut write_buffer, true)?;
final_result.extend(write_buffer.take_read_buffer().take_remaining().iter().map(|&i| i));
match result {
BufferResult::BufferUnderflow => break,
BufferResult::BufferOverflow => { }
}
}
Ok(final_result)
}
fn string_to_fixed_array_32(s: &str) -> [u8; 32] {
s.as_bytes().try_into().expect("字符串转为[u8; 32]失败")
}