Skip to content

Instantly share code, notes, and snippets.

@mbrubeck
Created February 16, 2017 20:02
Show Gist options
  • Save mbrubeck/8415d2d7f58d03abe164cc21c1e81023 to your computer and use it in GitHub Desktop.
Save mbrubeck/8415d2d7f58d03abe164cc21c1e81023 to your computer and use it in GitHub Desktop.
extern crate crypto;
extern crate rand;
use crypto::aes;
use crypto::buffer::{ReadBuffer, WriteBuffer, RefReadBuffer, RefWriteBuffer, BufferResult};
use crypto::blockmodes::PkcsPadding;
use rand::{Rng, OsRng};
use std::fs::File;
use std::io;
use std::io::prelude::*;
fn main() {
let mut args = std::env::args();
args.next();
let src = args.next().unwrap();
let dst = args.next().unwrap();
match run(&src, &dst) {
Ok(_) => {}
Err(e) => println!("{:?}", e)
}
}
fn run(src_path: &str, dst_path: &str) -> io::Result<()> {
let mut key = [0; 32];
let mut iv = [0; 16];
let mut rng = OsRng::new()?;
rng.fill_bytes(&mut key);
rng.fill_bytes(&mut iv);
let src = File::open(src_path)?;
let dst = File::create(dst_path)?;
let mut cyphertext = Vec::<u8>::new();
encrypt(src, &mut cyphertext, &key, &iv)?;
decrypt(&cyphertext[..], dst, &key, &iv)?;
Ok(())
}
fn encrypt<R: Read, W: Write>(mut src: R, mut dst: W, key: &[u8], iv: &[u8]) -> io::Result<()> {
let mut encryptor = aes::cbc_encryptor(aes::KeySize::KeySize192, key, iv, PkcsPadding);
let mut input = [0; 1024];
let mut output = [0; 1024];
loop {
let bytes_read = src.read(&mut input)?;
if bytes_read == 0 {
break
}
let mut read_buffer = RefReadBuffer::new(&input[..bytes_read]);
let mut write_buffer = RefWriteBuffer::new(&mut output);
loop {
let res = encryptor.encrypt(&mut read_buffer, &mut write_buffer, true)
.expect("encrypt error");
dst.write_all(write_buffer.take_read_buffer().take_remaining())?;
match res {
BufferResult::BufferUnderflow => break,
BufferResult::BufferOverflow => continue,
}
}
}
Ok(())
}
fn decrypt<R: Read, W: Write>(mut src: R, mut dst: W, key: &[u8], iv: &[u8]) -> io::Result<()> {
let mut decryptor = aes::cbc_decryptor(aes::KeySize::KeySize192, key, iv, PkcsPadding);
let mut input = [0; 1024];
let mut output = [0; 1024];
loop {
let bytes_read = src.read(&mut input)?;
if bytes_read == 0 {
break
}
let mut read_buffer = RefReadBuffer::new(&input[..bytes_read]);
let mut write_buffer = RefWriteBuffer::new(&mut output);
loop {
let res = decryptor.decrypt(&mut read_buffer, &mut write_buffer, true)
.expect("decrypt error");
dst.write_all(write_buffer.take_read_buffer().take_remaining())?;
match res {
BufferResult::BufferUnderflow => break,
BufferResult::BufferOverflow => continue,
}
}
}
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment