From dcc61cab436674191a83ba59b926d25c371f3d34 Mon Sep 17 00:00:00 2001 From: OBJNULL Date: Fri, 14 Jun 2024 13:43:36 -0400 Subject: [PATCH] Added basic encrypted authentication with a passphrase --- .gitignore | 2 ++ Cargo.toml | 8 ++++++++ src/auth.rs | 25 +++++++++++++++++++++++++ src/interface.rs | 22 ++++++++++++++++++++++ src/main.rs | 21 +++++++++++++++++++++ src/resource.rs | 19 +++++++++++++++++++ src/secure.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 138 insertions(+) create mode 100644 Cargo.toml create mode 100644 src/auth.rs create mode 100644 src/interface.rs create mode 100644 src/main.rs create mode 100644 src/resource.rs create mode 100644 src/secure.rs diff --git a/.gitignore b/.gitignore index 3ca43ae..f2700a5 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb +# Ignore resources +res/**.dat \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f37c4c0 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "RustyPass" +version = "0.1.0" +edition = "2021" + +[dependencies] +base64 = "0.22.1" +ring = "0.17.8" diff --git a/src/auth.rs b/src/auth.rs new file mode 100644 index 0000000..78cd46b --- /dev/null +++ b/src/auth.rs @@ -0,0 +1,25 @@ +// Libraries +use crate::{resource, secure}; + +// Structures +pub struct Auth { + pub verified: bool, + pub username: String +} + +// Implementations +impl Auth { + pub fn authenticate(username: String, password: String) -> Self { + // Read from the Auth file + let file_auth: resource::ResourceFile = resource::ResourceFile::init("res/auth.dat"); + + // Decrypting the content of the file with the password + let auth_plaintext: String = secure::Secure::decrypt(file_auth.content, password); + + // Testing if the user is authenticated: + let auth_status: bool = auth_plaintext == username; + + // Returning the result + return Auth {verified: auth_status, username: username}; + } +} \ No newline at end of file diff --git a/src/interface.rs b/src/interface.rs new file mode 100644 index 0000000..53cd31e --- /dev/null +++ b/src/interface.rs @@ -0,0 +1,22 @@ +// Libraries +use std::io; + +// Functions +pub fn int_auth() -> (String, String) { + // Variables + let mut username: String = String::new(); + let mut password: String = String::new(); + + // Asking for the username + println!(" - LOGIN - "); + println!("Username: "); + io::stdin().read_line(&mut username).expect("Failed to read line"); + username = String::from(username.to_lowercase().trim()); + + // Asking for the password + println!("Password: "); + io::stdin().read_line(&mut password).expect("Failed to read line"); + password = String::from(password.trim()); + + return (username, password); +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..ef07c1c --- /dev/null +++ b/src/main.rs @@ -0,0 +1,21 @@ +use interface::int_auth; + +// Libraries +mod interface; +mod resource; +mod secure; +mod auth; + +// Functions + +// Entry-Point +fn main() { + // Asking user for login credentials + let (username, password) = int_auth(); + + // Verify the user + let auth_profile: auth::Auth = auth::Auth::authenticate(username, password); + + // DEBUG: Testing if the user is authenticated + println!("Authenticated Status: {}", auth_profile.verified); +} \ No newline at end of file diff --git a/src/resource.rs b/src/resource.rs new file mode 100644 index 0000000..a6872e4 --- /dev/null +++ b/src/resource.rs @@ -0,0 +1,19 @@ +// Libraries +use std::fs; + +// Structures +pub struct ResourceFile { + pub path: String, + pub content: String +} + +// Implementations +impl ResourceFile { + pub fn init(file_path: &str) -> Self { + // Reading from a file: + let content: String = fs::read_to_string(String::from(file_path)).expect("Failed to read file."); + + // Returning the value: + return ResourceFile {path: String::from(file_path), content}; + } +} \ No newline at end of file diff --git a/src/secure.rs b/src/secure.rs new file mode 100644 index 0000000..d244a1a --- /dev/null +++ b/src/secure.rs @@ -0,0 +1,41 @@ +// Libraries +use ring::rand::{SecureRandom, SystemRandom}; + +// Constants + +// Structs +pub struct Secure{ + +} + +// Implementations +impl Secure { + // Takes in plaintext and a key to encrypt it + pub fn encrypt(value: String, key: String) -> String { + let rng = SystemRandom::new(); + let value_bytes = value.as_bytes(); + let key_bytes = key.as_bytes(); + + let mut ciphertext = vec![0u8; value_bytes.len()]; + rng.fill(&mut ciphertext).expect("Encryption Failed"); + + for i in 0..value_bytes.len() { + ciphertext[i] = value_bytes[i] ^ key_bytes[i % key_bytes.len()]; + } + + return base64::encode(ciphertext); + } + // Takes in cyphertext and a key to decrypt it + pub fn decrypt(cyphertext: String, key: String) -> String { + let cyphertext_bytes = base64::decode(cyphertext).expect("(0) Decryption Failed"); + let key_bytes = key.as_bytes(); + + let mut plaintext = vec![0u8; cyphertext_bytes.len()]; + + for i in 0..cyphertext_bytes.len() { + plaintext[i] = cyphertext_bytes[i] ^ key_bytes[i % key_bytes.len()]; + } + + return String::from_utf8(plaintext).expect("(1) Decryption Failed"); + } +} \ No newline at end of file