Initial commit

This commit is contained in:
Pablu23
2023-02-02 22:02:23 +01:00
commit edacd660fe
4 changed files with 522 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/target/*
.vscode

249
Cargo.lock generated Normal file
View File

@@ -0,0 +1,249 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "blake2b_simd"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127"
dependencies = [
"arrayref",
"arrayvec",
"constant_time_eq",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chacha20"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7fc89c7c5b9e7a02dfe45cd2367bae382f9ed31c61ca8debe5f827c420a2f08"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]]
name = "cipher"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e"
dependencies = [
"crypto-common",
"inout",
]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "cpufeatures"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
dependencies = [
"libc",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
dependencies = [
"cfg-if",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "folder_encryptor"
version = "0.1.0"
dependencies = [
"chacha20",
"rand",
"rand_core",
"rpassword",
"rust-argon2",
]
[[package]]
name = "generic-array"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "inout"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [
"generic-array",
]
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "rpassword"
version = "7.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322"
dependencies = [
"libc",
"rtoolbox",
"winapi",
]
[[package]]
name = "rtoolbox"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "rust-argon2"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b50162d19404029c1ceca6f6980fe40d45c8b369f6f44446fa14bb39573b5bb9"
dependencies = [
"base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
]
[[package]]
name = "typenum"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

13
Cargo.toml Normal file
View File

@@ -0,0 +1,13 @@
[package]
name = "folder_encryptor"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chacha20 = "0.9.0"
rand = "0.8.5"
rand_core = "0.6.4"
rpassword = "7.2.0"
rust-argon2 = "1.0.0"

258
src/main.rs Normal file
View File

@@ -0,0 +1,258 @@
use chacha20::cipher::{KeyIvInit, StreamCipher};
use chacha20::XChaCha20;
use rand::RngCore;
use rand_core::OsRng;
use std::path::Path;
use std::{
env,
fs,
fs::File,
io,
io::{Read, Write},
// time::SystemTime,
};
extern crate rpassword;
use rpassword::read_password;
const BUFFER_LEN: usize = 50 * 1024 * 1024; // 50 MiB
fn encrypt_file(
source_path: String,
dest_path: String,
nonce: &[u8; 24],
key: &Vec<u8>,
) -> io::Result<()> {
let mut cipher = XChaCha20::new(key[..32].as_ref().into(), nonce.into());
let source_file = Path::new(&source_path);
if !source_file.try_exists()? {
return Err(io::Error::from(io::ErrorKind::NotFound));
}
let file_name = source_file.file_name().unwrap_or_default();
let path = dest_path + "/" + file_name.to_str().unwrap_or_default() + ".cha";
if Path::new(&path).try_exists()? {
fs::remove_file(&path)?;
}
let mut source_file = File::open(source_path)?;
let mut dest_file = File::create(path)?;
// Stack allocated buffer
// let mut buffer = [0u8; BUFFER_LEN];
// Heap allocated buffer (Allows larger sized buffer, up to 50 % max ram)
let mut buffer = vec![0u8; BUFFER_LEN].into_boxed_slice();
dest_file.write(nonce)?;
loop {
let read_count = source_file.read(&mut buffer).unwrap();
if read_count == BUFFER_LEN {
cipher.apply_keystream(&mut buffer);
dest_file.write(&buffer).unwrap();
} else {
cipher.apply_keystream(&mut buffer[..read_count]);
dest_file.write(&buffer[..read_count]).unwrap();
break;
}
}
return Ok(());
}
fn decrypt_file(source_path: String, pwd: &String, config: &argon2::Config) -> io::Result<()> {
let mut nonce = [0u8; 24];
let path_info = Path::new(&source_path);
if !path_info.try_exists()? {
return Err(io::Error::from(io::ErrorKind::NotFound));
}
let path = &source_path[..&source_path.len() - 4];
if Path::new(&path).exists() {
fs::remove_file(&path)?;
}
let mut source_file = File::open(&source_path)?;
let mut dest_file = File::create(path)?;
source_file.read(&mut nonce)?;
let key = argon2::hash_raw(pwd.as_bytes(), &nonce, &config).unwrap();
let mut cipher = XChaCha20::new(key[..32].as_ref().into(), &nonce.into());
// Stack allocated buffer
// let mut buffer = [0u8; BUFFER_LEN];
// Heap allocated buffer (Allows larger sized buffer, up to 50 % max ram)
let mut buffer = vec![0u8; BUFFER_LEN].into_boxed_slice();
loop {
let read_count = source_file.read(&mut buffer).unwrap();
if read_count == BUFFER_LEN {
cipher.apply_keystream(&mut buffer);
dest_file.write(&buffer).unwrap();
} else {
cipher.apply_keystream(&mut buffer[..read_count]);
dest_file.write(&buffer[..read_count]).unwrap();
break;
}
}
return Ok(());
}
fn main() -> io::Result<()> {
let config = argon2::Config {
variant: argon2::Variant::Argon2id,
hash_length: 32,
lanes: 8,
mem_cost: 16 * 1024,
time_cost: 8,
..Default::default()
};
let exe = env::current_exe().unwrap();
let cwd = env::current_dir().unwrap();
let private = cwd.join("private");
if private.exists() {
let paths = fs::read_dir(&private).unwrap();
print!("Type password for encrypted files: ");
std::io::stdout().flush().unwrap();
let pwd = read_password().unwrap();
for path_result in paths {
let path = path_result.unwrap().path();
if path.is_file() {
decrypt_file(String::from(path.to_str().unwrap()), &pwd, &config)?;
fs::remove_file(String::from(path.to_str().unwrap()))?;
}
}
//fs::remove_dir_all(private).unwrap();
} else {
let paths = fs::read_dir(&cwd).unwrap();
for path_result in paths {
let path = path_result.unwrap().path();
if path.is_file() && path != exe {
println!("{path:?}");
}
}
println!("Encrypt files? [y]es / [n]o");
let input: u8 = std::io::stdin().bytes().next().unwrap().unwrap();
match input {
b'n' => return Ok(()),
b'y' => (),
_ => panic!("Input was not correct!"),
}
fs::create_dir(&private).unwrap();
print!("Type password to encrypt files: ");
std::io::stdout().flush().unwrap();
let pwd = read_password().unwrap();
let mut nonce = [0u8; 24];
OsRng.fill_bytes(&mut nonce);
let key = argon2::hash_raw(pwd.as_bytes(), &nonce, &config).unwrap();
let paths = fs::read_dir(cwd).unwrap();
for path_result in paths {
let path = path_result.unwrap().path();
if path.is_file() && path != exe {
encrypt_file(
String::from(path.to_str().unwrap()),
String::from(private.to_str().unwrap()),
&nonce,
&key,
)
.unwrap();
}
}
}
// let start = SystemTime::now();
// let source_path = String::from("E:\\Programieren\\Rust\\folder_encryptor\\1gb.test.bin.cha");
// // let plaintext: String = String::from("Das ist ein Test string");
// let pwd: String = String::from("TestPassword!");
// // let mut nonce = [0u8; 24];
// // OsRng.fill_bytes(&mut nonce);
// // let key = argon2::hash_raw(pwd.as_bytes(), &nonce, &config).unwrap();
// decrypt_file(source_path, &pwd, &config)?;
// let encrypt_time = start.elapsed().unwrap();
// println!("Encrypt took {encrypt_time:?}");
Ok(())
// let start = SystemTime::now();
// Decrypt Part
//dist_file.seek(SeekFrom::Start(0)).unwrap();
// drop(dist_file);
// cipher.seek(0u32);
// let mut dist_file = File::open(dist_path).unwrap();
// let decrypted_path = source_path.clone() + ".decrypted.bin";
// let mut decrypted_file = File::create(decrypted_path).unwrap();
// let mut read_nonce = [0u8; 24];
// let nonce_size = dist_file.read(&mut read_nonce).unwrap();
// assert_eq!(24, nonce_size);
// assert_eq!(read_nonce, nonce);
// let t = dist_file.stream_position().unwrap();
// println!("{t}");
// let mut decrypt_buffer = [0u8; BUFFER_LEN];
// loop {
// let read_count = dist_file.read(&mut decrypt_buffer).unwrap();
// println!("Decrypt Read: {read_count}");
// if read_count == BUFFER_LEN {
// cipher.apply_keystream(&mut decrypt_buffer);
// decrypted_file.write(&decrypt_buffer).unwrap();
// } else {
// cipher.apply_keystream(&mut decrypt_buffer[..read_count]);
// decrypted_file.write(&decrypt_buffer[..read_count]).unwrap();
// break;
// }
// }
// let decrypt_time = start.elapsed().unwrap();
// println!("Encrypt took {encrypt_time:?}");
// println!("Decrypt took {decrypt_time:?}");
}