Merge remote-tracking branch 'origin/master'

master
Trivernis 5 years ago
commit 273497cf40

@ -5,7 +5,6 @@ use des::Des;
use rand::Rng; use rand::Rng;
use rayon::prelude::*; use rayon::prelude::*;
use std::sync::Mutex; use std::sync::Mutex;
use std::time::Instant;
type DesCfb = Cfb<Des>; type DesCfb = Cfb<Des>;
@ -38,7 +37,6 @@ pub fn decrypt_with_dictionary(
checksum: &[u8], checksum: &[u8],
) -> Option<Vec<u8>> { ) -> Option<Vec<u8>> {
let decrypted = Mutex::<Option<Vec<u8>>>::new(None); let decrypted = Mutex::<Option<Vec<u8>>>::new(None);
let start = Instant::now();
let pass = dict.par_iter().find_first(|(_pw, key)| { let pass = dict.par_iter().find_first(|(_pw, key)| {
let decrypted_data = decrypt_data(&data, key); let decrypted_data = decrypt_data(&data, key);
let decr_check = sha_checksum(&decrypted_data); let decr_check = sha_checksum(&decrypted_data);
@ -51,11 +49,7 @@ pub fn decrypt_with_dictionary(
}; };
}); });
if let Some((pw, _key)) = pass { if let Some((pw, _key)) = pass {
println!( println!("\nPassword found: {}", pw);
"\nPassword found in {:.2}s: {}",
start.elapsed().as_secs_f32(),
pw
);
let decry = decrypted.lock().unwrap(); let decry = decrypted.lock().unwrap();
if let Some(decrypted_data) = (*decry).clone() { if let Some(decrypted_data) = (*decry).clone() {
return Some(decrypted_data); return Some(decrypted_data);

@ -13,7 +13,7 @@ use rpassword::read_password_from_tty;
use spinners::{Spinner, Spinners}; use spinners::{Spinner, Spinners};
use std::fs; use std::fs;
use std::fs::File; use std::fs::File;
use std::io::{BufWriter, Write}; use std::io::{BufRead, BufReader, BufWriter, Write};
use std::sync::mpsc::sync_channel; use std::sync::mpsc::sync_channel;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
@ -128,29 +128,10 @@ fn decrypt(_opts: &Opts, args: &Decrypt) {
let data_checksum = base64::decode(bin_content.as_slice()).unwrap(); let data_checksum = base64::decode(bin_content.as_slice()).unwrap();
if let Some(dict) = dictionary { if let Some(dict) = dictionary {
let sp = spinner("Reading dictionary..."); if let Some(dec_data) = decrypt_with_dictionary_file(dict, &data, &data_checksum) {
let pw_table: Vec<PassKey>;
{
let dictionary = fs::read_to_string(dict).expect("Failed to read dictionary file!");
let lines = dictionary.par_lines();
pw_table = lines
.map(|line| {
let parts: Vec<&str> = line.split("\t").collect::<Vec<&str>>();
let pw = parts[0].to_string();
let key_str: String = parts[1].to_string();
let key = base64::decode(&key_str).unwrap();
(pw, key)
})
.collect();
}
sp.message("Dictionary decrypting file multithreaded".into());
if let Some(dec_data) = decrypt_with_dictionary(&data, pw_table, &data_checksum) {
sp.stop();
fs::write(output, &dec_data).expect("Failed to write output file!"); fs::write(output, &dec_data).expect("Failed to write output file!");
println!("\nFinished!"); println!("\nFinished!");
} else { } else {
sp.stop();
println!("\nNo password found!"); println!("\nNo password found!");
} }
} else { } else {
@ -218,3 +199,61 @@ fn create_dictionary(_opts: &Opts, args: &CreateDictionary) {
fn spinner(text: &str) -> Spinner { fn spinner(text: &str) -> Spinner {
Spinner::new(Spinners::Dots2, text.into()) Spinner::new(Spinners::Dots2, text.into())
} }
const LINES_PER_CHUNK: usize = 10000000;
fn decrypt_with_dictionary_file(
filename: String,
data: &Vec<u8>,
data_checksum: &Vec<u8>,
) -> Option<Vec<u8>> {
let sp = spinner("Reading dictionary...");
let f = File::open(&filename).expect("Failed to open dictionary file.");
let reader = BufReader::new(f);
let mut pb =
ProgressBar::new((get_line_count(&filename) as f64 / LINES_PER_CHUNK as f64).ceil() as u64);
let (rx, tx) = sync_channel::<Vec<String>>(10);
let _handle = thread::spawn(move || {
let mut line_vec: Vec<String> = vec![];
reader.lines().for_each(|line_result| {
if line_vec.len() > LINES_PER_CHUNK {
if let Err(_) = rx.send(line_vec.clone()) {}
line_vec.clear();
}
match line_result {
Ok(line) => line_vec.push(line),
Err(err) => eprintln!("Failed with err {}", err),
}
});
if let Err(_) = rx.send(line_vec.clone()) {}
line_vec.clear();
});
sp.stop();
let mut result_data: Option<Vec<u8>> = None;
for lines in tx {
let pw_table: Vec<PassKey> = lines
.par_iter()
.map(|line| {
let parts: Vec<&str> = line.split("\t").collect::<Vec<&str>>();
let pw = parts[0].parse().unwrap();
let key_str: String = parts[1].parse().unwrap();
let key = base64::decode(&key_str).unwrap();
(pw, key)
})
.collect();
pb.inc();
if let Some(dec_data) = decrypt_with_dictionary(&data, pw_table, &data_checksum) {
result_data = Some(dec_data);
break;
}
}
pb.finish();
result_data
}
fn get_line_count(fname: &str) -> usize {
let f = File::open(fname).expect("Failed to open file to get the line count.");
let reader = BufReader::new(f);
return reader.lines().count();
}

Loading…
Cancel
Save