encryptify_lib/
encryptor_decryptor.rs

1use aes::Aes256;
2use block_modes::{block_padding::Pkcs7, BlockMode, Cbc};
3use std::{
4    fs::{self, File},
5    io::Write,
6};
7
8use crate::zipper::zip_folder;
9
10type Aes256Cbc = Cbc<Aes256, Pkcs7>;
11
12/// Encrypts a file using AES-256 encryption.
13///
14/// # Arguments
15///
16/// * `file_path` - Path of the file to encrypt.
17/// * `key` - The encryption key. (32 bytes)
18///
19/// # Panics
20///
21/// This function will panic if:
22/// - The file cannot be read.
23/// - The output file cannot be created.
24/// - The encrypted data cannot be written to the output file.
25///
26pub fn encrypt_file(file_path: &str, key: &[u8]) {
27    let file_content = fs::read(file_path).expect("Failed to read the file");
28
29    let iv = [0u8; 16]; // Initialization vector
30
31    let cipher = Aes256Cbc::new_from_slices(key, &iv).expect("Failed to create AES cipher");
32
33    let cipher_text = cipher.encrypt_vec(&file_content);
34
35    let mut output_file =
36        File::create(format!("{}.encrypted", file_path)).expect("Failed to create the output file");
37
38    output_file
39        .write_all(&cipher_text)
40        .expect("Failed to write encrypted data to the output file");
41}
42
43/// Decrypts an AES-256 encrypted file.
44///
45/// # Arguments
46///
47/// * `file_path` - Path of the file to decrypt.
48/// * `key` - The encryption key. (32 bytes)
49///
50/// # Panics
51///
52/// This function will panic if:
53/// - The file cannot be read.
54/// - The cipher cannot be created.
55/// - The output file cannot be created.
56/// - The decrypted data cannot be written to the output file.
57pub fn decrypt_file(file_path: &str, key: &[u8]) {
58    let encrypted_content = fs::read(file_path).expect("Failed to read the encrypted file");
59
60    let iv = [0u8; 16];
61
62    let cipher = Aes256Cbc::new_from_slices(key, &iv).expect("Failed to create AES cipher");
63
64    let decrypted_content = cipher
65        .decrypt_vec(&encrypted_content)
66        .expect("Failed to decrypt data");
67
68    let mut output_file =
69        File::create(format!("{}.decrypted", file_path)).expect("Failed to create the output file");
70
71    output_file
72        .write_all(&decrypted_content)
73        .expect("Failed to write decrypted data to the output file");
74}
75
76pub fn encrypt_folder(folder_path: &str, key: &[u8]) {
77    let zip_path = format!("{}.zip", folder_path);
78    zip_folder(folder_path, &zip_path);
79    encrypt_file(&zip_path, key);
80    fs::remove_file(&zip_path).expect("Failed to remove the intermediate zip file :|");
81}
82
83pub fn decrypt_folder(file_path: &str, key: &[u8]) {
84    decrypt_file(file_path, key);
85
86    let zip_path = format!("{}.decrypted", file_path); // As the decrypt file function appends .decrypted to the file name
87
88    let zip_file = File::open(&zip_path).expect("Failed to open the decrypted zip file");
89
90    let mut archive = zip::ZipArchive::new(zip_file).expect("Failed to read the Zip archive");
91
92    let output_folder = file_path.trim_end_matches(".zip.encrypted");
93
94    fs::create_dir(output_folder).expect("Failed to create the output folder");
95
96    for i in 0..archive.len() {
97        let mut file = archive
98            .by_index(i)
99            .expect("Failed to get the file from the archive");
100
101        let output_file_path = format!("{}/{}", output_folder, file.name()); // TODO: Fix security flaw here, needs sanitization
102
103        let mut output_file =
104            File::create(output_file_path).expect("Failed to create the output file");
105
106        std::io::copy(&mut file, &mut output_file)
107            .expect("Failed to copy contents to extracted file.");
108    }
109
110    fs::remove_file(&zip_path).expect("Failed to delete the intermediate 'decrypted' zip file");
111}