diff --git a/src/lib/crypt.rs b/src/lib/crypt.rs index 736b78b..7cefb21 100644 --- a/src/lib/crypt.rs +++ b/src/lib/crypt.rs @@ -1,14 +1,14 @@ -use rand::Rng; +use crate::lib::hash::{sha_checksum, PassKey}; +use cfb_mode::stream_cipher::{NewStreamCipher, StreamCipher}; use cfb_mode::Cfb; use des::Des; -use cfb_mode::stream_cipher::{NewStreamCipher, StreamCipher}; +use rand::Rng; use rayon::prelude::*; -use crate::lib::hash::{PassKey, sha_checksum}; type DesCfb = Cfb; pub struct EncryptionKeys { - current: u64 + current: u64, } impl Iterator for EncryptionKeys { @@ -27,9 +27,7 @@ impl Iterator for EncryptionKeys { impl EncryptionKeys { pub fn new() -> Self { - Self { - current: 0 - } + Self { current: 0 } } } @@ -54,7 +52,11 @@ pub fn decrypt_data(data: &[u8], key: &[u8]) -> Vec { } /// Decrypts data using a dictionary -pub fn decrypt_with_dictionary(data: &[u8], dict: Vec, checksum: &[u8]) -> Option> { +pub fn decrypt_with_dictionary( + data: &[u8], + dict: Vec, + checksum: &[u8], +) -> Option> { let pass = dict.par_iter().find_first(|(_pw, key)| { let decrypted_data = decrypt_data(&data, key); let decr_check = sha_checksum(&decrypted_data); @@ -75,17 +77,19 @@ pub fn decrypt_with_dictionary(data: &[u8], dict: Vec, checksum: &[u8]) /// Decrypts data by generating all possible keys pub fn decrypt_brute_brute_force(data: &[u8], checksum: &[u8]) -> Option> { - let encryption_key = (0u64..std::u64::MAX).into_par_iter().find_first(|num: &u64| { - let key: &[u8] = &num.to_le_bytes(); - let decrypted_data = decrypt_data(&data, key); - let decr_check = sha_checksum(&decrypted_data); + let encryption_key = (0u64..std::u64::MAX) + .into_par_iter() + .find_first(|num: &u64| { + let key: &[u8] = &num.to_le_bytes(); + let decrypted_data = decrypt_data(&data, key); + let decr_check = sha_checksum(&decrypted_data); - if decr_check == checksum { - true - } else { - false - } - }); + if decr_check == checksum { + true + } else { + false + } + }); if let Some(num) = encryption_key { let key: &[u8] = &num.to_le_bytes(); println!("Key found: {:?}", key); @@ -93,4 +97,4 @@ pub fn decrypt_brute_brute_force(data: &[u8], checksum: &[u8]) -> Option } else { None } -} \ No newline at end of file +} diff --git a/src/lib/hash.rs b/src/lib/hash.rs index a648ae6..49f79a7 100644 --- a/src/lib/hash.rs +++ b/src/lib/hash.rs @@ -1,5 +1,5 @@ -use sha2::{Sha256, Digest}; use rayon::prelude::*; +use sha2::{Digest, Sha256}; pub type PassKey = (String, Vec); @@ -14,10 +14,13 @@ pub fn create_key(pw: String) -> Vec { /// Maps a list of passwords to keys and returns a vector of pairs pub fn map_to_keys(passwords: Vec<&String>) -> Vec { - return passwords.par_iter().map(|pw| { - let pw_str = (*pw).clone(); - (pw_str.clone(), create_key(pw_str)) - }).collect(); + return passwords + .par_iter() + .map(|pw| { + let pw_str = (*pw).clone(); + (pw_str.clone(), create_key(pw_str)) + }) + .collect(); } /// Creates a sha256 hashsum from the input data diff --git a/src/main.rs b/src/main.rs index af10b67..4925e0a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,16 @@ pub mod lib; -use structopt::StructOpt; -use std::fs::File; -use std::io::{Read, Write}; -use crate::lib::crypt::{encrypt_data, decrypt_data, decrypt_with_dictionary, decrypt_brute_brute_force}; -use rpassword; -use rpassword::{read_password_from_tty}; + +use crate::lib::crypt::{ + decrypt_brute_brute_force, decrypt_data, decrypt_with_dictionary, encrypt_data, +}; use crate::lib::hash::{create_key, map_to_keys, sha_checksum, PassKey}; -use rayon::prelude::*; use itertools::Itertools; +use rayon::prelude::*; +use rpassword; +use rpassword::read_password_from_tty; +use std::fs::File; +use std::io::{Read, Write}; +use structopt::StructOpt; #[derive(StructOpt, Clone)] #[structopt(name = "destools", version = "1.0", author = "Julius R.")] @@ -18,7 +21,6 @@ struct Opts { #[derive(StructOpt, Clone)] enum SubCommand { - /// Encrypt a file with des #[structopt(name = "encrypt")] Encrypt(Encrypt), @@ -29,7 +31,7 @@ enum SubCommand { /// Create a dictionary rainbow-table from a txt file #[structopt(name = "create-dictionary")] - CreateDictionary(CreateDictionary) + CreateDictionary(CreateDictionary), } #[derive(StructOpt, Clone)] @@ -65,7 +67,7 @@ struct Decrypt { /// The file needs to be in a csv format with calculated password hashes. /// The hashes can be calculated with the create-dictionary subcommand from a txt file. #[structopt(short = "d", long = "dictionary")] - dictionary: Option + dictionary: Option, } #[derive(StructOpt, Clone)] @@ -122,13 +124,16 @@ fn decrypt(_opts: &Opts, args: &Decrypt) { let dictionary = read_file(dict); let lines = dictionary.lines().collect::>(); - let pw_table: Vec = lines.par_iter().map(|line| { - let parts: Vec<&str> = line.split(",").collect::>(); - let pw = parts[0].parse().unwrap(); - let key_str: String = parts[1].parse().unwrap(); - let key = base64::decode(&key_str).unwrap(); - (pw, key) - }).collect(); + let pw_table: Vec = lines + .par_iter() + .map(|line| { + let parts: Vec<&str> = line.split(",").collect::>(); + let pw = parts[0].parse().unwrap(); + let key_str: String = parts[1].parse().unwrap(); + let key = base64::decode(&key_str).unwrap(); + (pw, key) + }) + .collect(); println!("Starting multithreaded decryption..."); if let Some(dec_data) = decrypt_with_dictionary(&data, pw_table, &data_checksum) { @@ -156,14 +161,15 @@ fn decrypt(_opts: &Opts, args: &Decrypt) { /// Creates a dictionary from an input file and writes it to the output file fn create_dictionary(_opts: &Opts, args: &CreateDictionary) { - let input = (*args.input).parse().unwrap(); + let input = (*args.input).parse().unwrap(); let contents = read_file(input); let lines = contents.lines().collect::>(); println!("Parsing {} passwords...", lines.len()); - let pws: Vec = lines.par_iter().map(| s | -> String { - s.parse().unwrap() - }).collect(); + let pws: Vec = lines + .par_iter() + .map(|s| -> String { s.parse().unwrap() }) + .collect(); println!("Removing duplicates..."); let passwords = pws.iter().unique().collect_vec(); println!("Mapping passwords to keys..."); @@ -190,7 +196,7 @@ fn read_file_binary(filename: String) -> Vec { /// Reads a file to the end and returns the contents as a string fn read_file(filename: String) -> String { let mut fin = File::open(filename).unwrap(); - let mut contents= String::new(); + let mut contents = String::new(); fin.read_to_string(&mut contents).unwrap(); return contents; } @@ -199,4 +205,4 @@ fn read_file(filename: String) -> String { fn write_file(filename: String, data: &[u8]) { let mut fout = File::create(filename).unwrap(); fout.write(data).unwrap(); -} \ No newline at end of file +}