Day 3 - Rust File Encryptor/Decryptor
Rust's encryption basics with our file encryptor/decryptor. Learn file I/O, XOR encryption, and CLI usage in a concise project.
Introduction
Today, we're diving into the world of security with Rust by creating a simple file encryptor/decryptor. We'll use a basic XOR cipher for encryption, but remember, this is for educational purposes; never use this for actual secure data due to its simplicity.
Prerequisites
- Basic understanding of Rust
- Familiarity with file I/O operations
- Concept of encryption (even if basic)
Project Structure
Let's set up our project first:
mkdir rust-file-encryptor
cd rust-file-encryptor
cargo init --bin
Now, let’s define our folder structure:
rust-file-encryptor/
│
├── src/
│ ├── main.rs
│ ├── cli.rs
│ ├── encryption.rs
│ └── io.rs
│
├── Cargo.toml
└── README.md
Step 1: Setting up Cargo.toml
[package]
name = "file_encryptor"
version = "0.1.0"
edition = "2018"
[dependencies]
structopt = "0.3"
Step 2: cli.rs
- Handling Command Line Arguments
use structopt::StructOpt;
#[derive(StructOpt)]
struct Cli {
#[structopt(parse(from_os_str))]
input: std::path::PathBuf,
#[structopt(short, long)]
decrypt: bool,
}
pub fn parse_args() -> Cli {
Cli::from_args()
}
Step 3: encryption.rs
- Encryption Logic
pub fn encrypt_decrypt(data: &mut [u8], key: u8) {
data.iter_mut().for_each(|byte| *byte ^= key);
}
pub fn get_key() -> u8 {
42 // A simple key for demonstration
}
Step 4: io.rs
- File Operations
use std::fs;
use std::io::{Read, Write};
pub fn read_file(path: &std::path::Path) -> Result<Vec<u8>, std::io::Error> {
let mut file = fs::File::open(path)?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
Ok(buffer)
}
pub fn write_file(path: &std::path::Path, data: &[u8]) -> Result<(), std::io::Error> {
let mut file = fs::File::create(path)?;
file.write_all(data)?;
Ok(())
}
Step 5: main.rs
- Tying It All Together
mod cli;
mod encryption;
mod io;
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = cli::parse_args();
let key = encryption::get_key();
let mut data = io::read_file(&args.input)?;
if args.decrypt {
encryption::encrypt_decrypt(&mut data, key);
let output_path = args.input.with_extension("decrypted");
io::write_file(&output_path, &data)?;
println!("Decrypted file saved to: {:?}", output_path);
} else {
encryption::encrypt_decrypt(&mut data, key);
let output_path = args.input.with_extension("encrypted");
io::write_file(&output_path, &data)?;
println!("Encrypted file saved to: {:?}", output_path);
}
Ok(())
}
Step 6: Usage
To run your encryptor:
cargo run -- --input /path/to/file.txt
cargo run -- --input /path/to/file.txt --decrypt
Explanation
- CLI Parsing: We use
structopt
to handle command-line arguments, allowing users to specify files for encryption or decryption. - Encryption Logic: We've used a simple XOR operation for demonstrating encryption. XOR with the same key twice will decrypt the data, making this method symmetric.
- File I/O: The
io
module handles reading from and writing to files, ensuring we deal with file operations gracefully. - Main: Our main function reads the file, applies encryption or decryption based on the user's choice, and then writes the result back to a new file.
Conclusion
This project not only introduces you to basic encryption concepts in Rust but also teaches you about file handling, command-line interfaces, and modular programming. Remember, this is a stepping stone towards understanding more complex encryption algorithms like AES or RSA in future projects.
Feel free to extend this project by:
- Implementing more secure encryption methods.
- Adding error handling for common issues like file not found or permission denied.
- Creating a GUI interface using something like
egui
for a visual component to the encryptor/decryptor.
This step-by-step guide should have you encrypting and decrypting files with Rust in no time!