CrescentMnn / password_manager

This project is a simple password manager written for the command line interface (CLI) to help me learn Rust. It lets users securely store, manage, and retrieve passwords.
0 stars 0 forks source link

Read AES documentation for project #5

Open CrescentMnn opened 3 months ago

CrescentMnn commented 3 months ago

could make use of:

use aes::Aes128;
use aes::cipher::{
    BlockCipher, NewBlockCipher,
    generic_array::GenericArray,
    stream::{NewStreamCipher, StreamCipherCore},
};

fn encrypt_decrypt_password(password: &str) {
    // Key for AES encryption (16 bytes)
    let key = GenericArray::from_slice(b"very_secure_key123");

    // Convert password string to bytes
    let password_bytes = password.as_bytes();

    // Initialize AES cipher with the key
    let cipher = Aes128::new(&key);

    // Encrypt the password
    let mut encrypted_password = password_bytes.to_vec();
    cipher.encrypt_block(&mut GenericArray::from_mut_slice(&mut encrypted_password));

    // Decrypt the encrypted password
    cipher.decrypt_block(&mut GenericArray::from_mut_slice(&mut encrypted_password));

    // Convert decrypted bytes back to string
    let decrypted_password = String::from_utf8_lossy(&encrypted_password);

    println!("Original password: {}", password);
    println!("Encrypted password: {:?}", encrypted_password);
    println!("Decrypted password: {}", decrypted_password);
}

fn main() {
    let password = "my_secret_password";

    encrypt_decrypt_password(password);
}
CrescentMnn commented 3 months ago

found new function that could work for this:


extern crate aes;
extern crate block_modes;
extern crate sha2;

use aes::Aes256;
use block_modes::{BlockMode, Cbc, block_padding::Pkcs7};
use sha2::{Digest, Sha256};
use std::env;
use openssl::rand::rand_bytes;

type Aes256Cbc = Cbc<Aes256, Pkcs7>;

fn main() {

    let password = "Xes;aDdvAnYE#7_Q2Zq,k";
    // Hash the password to get a 32-byte key
    let key = Sha256::digest("q3Jcf&Dgp`X)BK5bU8*h+".as_bytes());
    //encrypt_text(&key, password);
    decrypt_text(&key, &encrypt_text(&key, password));

   /* match action.as_str() {
        "encrypt" => encrypt_text(&key, text),
        "decrypt" => decrypt_text(&key, text),
        _ => println!("Invalid action. Use 'encrypt' or 'decrypt'."),
    }*/

}

// Encrypts the text and prints the encrypted data in hexadecimal
fn encrypt_text(key: &[u8], text: &str) -> String {
    // Generate random IV
    let mut iv = [0u8; 16];
    rand_bytes(&mut iv).expect("Failed to generate random IV");

    // Create the cipher
    let cipher = Aes256Cbc::new_from_slices(&key, &iv).unwrap();

    // Encrypt the text
    let mut encrypted_data = cipher.encrypt_vec(text.as_bytes());
    encrypted_data = [&iv[..], &encrypted_data[..]].concat();

    // Print the encrypted data in hexadecimal
    let encrypted_hex = hex::encode(encrypted_data);
    println!("Encrypted data: {}", encrypted_hex);

    encrypted_hex
}

// Decrypts the text and prints the decrypted data
fn decrypt_text(key: &[u8], text: &str) {
    // Parse the IV and ciphertext from the input
    let data = match hex::decode(text) {
        Ok(data) => data,
        Err(_) => {
            println!("Invalid input data. Must be a valid hex-encoded string.");
            return;
        }
    };
    let (iv, ciphertext) = data.split_at(16);

    // Create the cipher
    let cipher = Aes256Cbc::new_from_slices(&key, iv).unwrap();

    // Decrypt the ciphertext
    let decrypted_data = match cipher.decrypt_vec(ciphertext) {
        Ok(data) => data,
        Err(_) => {
            println!("Decryption failed. Ensure the provided password and encrypted data are correct.");
            return;
        }
    };

    // Convert to a string and print
    let decrypted_text = match String::from_utf8(decrypted_data) {
        Ok(text) => text,
        Err(_) => {
            println!("Decrypted data contains invalid UTF-8 characters.");
            return;
        }
    };
    println!("Decrypted text: {}", decrypted_text);
}

Found this snippet on another repo for a different project, will reference later...

Reference: https://github.com/KunalBagaria/secretkeeper

CrescentMnn commented 3 months ago

DOCUMENTATION MISSING

Previous example worked, I've yet to integrate it fully. I'm still looking for the corresponding documentation to be able to understand how it works and be able to prevent any errors in that part.

Dependencies used

[dependencies]
bcrypt = "0.15"
aes = "0.7.5"
block-modes = "0.8.1"
sha2 = "0.10.0"
hex = "0.4.3"
openssl = "0.10.38"

the functions used to encrypt and decrypt, encrypt_vec() and decrypt_vec are supposedly found in block-modes, although I haven't found good documentation regarding said dependency.

So far the only messages we get when running cargo check are the following:


warning: unused import: `Sha256`
 --> src/main.rs:8:20
  |
8 | use sha2::{Digest, Sha256};
  |                    ^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused import: `std::env`
 --> src/main.rs:9:5
  |
9 | use std::env;
  |     ^^^^^^^^

warning: unused import: `verify`
  --> src/main.rs:15:20
   |
15 | use bcrypt::{hash, verify, DEFAULT_COST};
   |                    ^^^^^^

warning: unused import: `Digest`
 --> src/main.rs:8:12
  |
8 | use sha2::{Digest, Sha256};
  |            ^^^^^^

warning: type alias `Aes256Cbc` is never used
  --> src/main.rs:12:6
   |
12 | type Aes256Cbc = Cbc<Aes256, Pkcs7>;
   |      ^^^^^^^^^
   |
   = note: `#[warn(dead_code)]` on by default

warning: field `password` is never read
  --> src/main.rs:36:5
   |
21 | struct SessionPassword {
   |        --------------- field in this struct
...
36 |     password : String,
   |     ^^^^^^^^

warning: function `encrypt_text` is never used
   --> src/main.rs:179:4
    |
179 | fn encrypt_text(key: &[u8], text: &str) -> String {
    |    ^^^^^^^^^^^^

warning: function `decrypt_text` is never used
   --> src/main.rs:200:4
    |
200 | fn decrypt_text(key: &[u8], text: &str) -> Result<String, String> {
    |    ^^^^^^^^^^^^

warning: function `encrypt_new_password` is never used
   --> src/main.rs:229:4
    |
229 | fn encrypt_new_password(){
    |    ^^^^^^^^^^^^^^^^^^^^

warning: function `decrypt_new_password` is never used
   --> src/main.rs:236:4
    |
236 | fn decrypt_new_password(){
    |    ^^^^^^^^^^^^^^^^^^^^

warning: `password_manager` (bin "password_manager") generated 10 warnings (run `cargo fix --bin "password_manager"` to apply 3 suggestions)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 6.12s

All cargo test functions work correctly.

CrescentMnn commented 3 months ago

Documentation for bcrypt

Crate https://docs.rs/bcrypt/latest/bcrypt/

Verify https://docs.rs/bcrypt/latest/bcrypt/fn.verify.html

pub fn verify<P: AsRef<[u8]>>(password: P, hash: &str) -> BcryptResult<bool>

Hash https://docs.rs/bcrypt/latest/bcrypt/fn.hash.html

pub fn hash<P: AsRef<[u8]>>(password: P, cost: u32) -> BcryptResult<String>