Added basic encrypted authentication with a passphrase
This commit is contained in:
parent
236f2a7aa0
commit
dcc61cab43
7 changed files with 138 additions and 0 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -14,3 +14,5 @@ Cargo.lock
|
||||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||||
*.pdb
|
*.pdb
|
||||||
|
|
||||||
|
# Ignore resources
|
||||||
|
res/**.dat
|
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "RustyPass"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
base64 = "0.22.1"
|
||||||
|
ring = "0.17.8"
|
25
src/auth.rs
Normal file
25
src/auth.rs
Normal file
|
@ -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};
|
||||||
|
}
|
||||||
|
}
|
22
src/interface.rs
Normal file
22
src/interface.rs
Normal file
|
@ -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);
|
||||||
|
}
|
21
src/main.rs
Normal file
21
src/main.rs
Normal file
|
@ -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);
|
||||||
|
}
|
19
src/resource.rs
Normal file
19
src/resource.rs
Normal file
|
@ -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};
|
||||||
|
}
|
||||||
|
}
|
41
src/secure.rs
Normal file
41
src/secure.rs
Normal file
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue