50 lines
1.5 KiB
Rust
50 lines
1.5 KiB
Rust
use aes::cipher::generic_array::GenericArray;
|
|
use aes::cipher::{BlockDecrypt, KeyInit};
|
|
use aes::Aes128;
|
|
use log::error;
|
|
use rustc_serialize::base64::FromBase64;
|
|
use std::error::Error;
|
|
use std::io::{read_to_string, stdin, Read};
|
|
|
|
fn decrypt_aes_ecb(input: &mut dyn Read) -> Result<String, Box<dyn Error>> {
|
|
let key = GenericArray::from_slice("YELLOW SUBMARINE".as_bytes());
|
|
let mut text = read_to_string(input)?.from_base64()?;
|
|
let len = text.len();
|
|
let cipher = Aes128::new(&key);
|
|
for block_nr in 0..len / 16 {
|
|
let block = GenericArray::from_mut_slice(&mut text[block_nr * 16..(block_nr + 1) * 16]);
|
|
cipher.decrypt_block(block);
|
|
}
|
|
Ok(String::from_utf8(
|
|
text[..len - text[len - 1] as usize].to_vec(),
|
|
)?)
|
|
}
|
|
|
|
fn main() {
|
|
env_logger::init();
|
|
|
|
match decrypt_aes_ecb(&mut stdin().lock()) {
|
|
Ok(s) => println!("{}", s),
|
|
Err(e) => error!("{}", e),
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use std::fs::File;
|
|
use std::io::BufReader;
|
|
use std::path::Path;
|
|
|
|
#[test]
|
|
fn challenge7_decrypt_aes_ecb() {
|
|
let cargo_manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
|
let testinput = File::open(cargo_manifest_dir.join("7.txt")).unwrap();
|
|
let decrypted = decrypt_aes_ecb(&mut BufReader::new(testinput)).unwrap();
|
|
let plaintext =
|
|
read_to_string(File::open(cargo_manifest_dir.join("7_plaintext.txt")).unwrap())
|
|
.unwrap();
|
|
assert_eq!(decrypted, plaintext);
|
|
}
|
|
}
|