Skip to content
Snippets Groups Projects
Unverified Commit e5d9c652 authored by Cheuk Pui Lam's avatar Cheuk Pui Lam
Browse files

feat(client):Finished encryption and decryption algorithm implementation

parent 85148e01
No related branches found
No related tags found
1 merge request!2feat(client): Client implementation
......@@ -20,10 +20,10 @@ pub enum Commands{
/// File path to be inputted
filename_option: Option<String>,
/// set searchable column to key
#[clap(long = "key")]
#[clap(long = "key", short = 'k')]
key_option: Option<String>,
/// set searchable index
#[clap(long = "index")]
#[clap(long = "index", short = 'i')]
index_option: Option<usize>,
},
/// Searches remote server with optional string
......
......@@ -2,28 +2,29 @@
pub mod keys{
use std::{fs::File, io::Read, os::unix::fs::MetadataExt, path::Path};
use anyhow::Result;
use chacha20poly1305::{aead::OsRng, KeyInit, XChaCha20Poly1305};
use log::debug;
use chacha20poly1305::{aead::OsRng, KeyInit, XChaCha20Poly1305};
/// Create key if not exist, otherwise read key
pub fn load_credentials() -> Result<(Vec<u8>, Vec<u8>)>{
// function to load key from file
fn load_from_file(fp: &Path) -> Result<Vec<u8>>{
// if file exists, load from file
// if not, create key and write to file
match fp.exists(){
true => {
debug!("{:?} exists, loading from file", fp);
let mut file = File::open(fp)?;
let metadata = file.metadata()?;
let mut buffer = vec![0; metadata.size() as usize];
// file.read_to_string(&mut content)?;
file.read(&mut buffer)?;
Ok(buffer)
}
false => {
debug!("{:?} does not exist, generating", fp);
// generate key
let key = XChaCha20Poly1305::generate_key(&mut OsRng).to_vec();
// let mut file = File::create(chacha_keypath)?;
// write to file
std::fs::write(fp,&key)?;
Ok(key)
},
......@@ -35,20 +36,55 @@ pub mod keys{
}
pub mod chacha{
use core::str;
use anyhow::{Result, anyhow};
use chacha20poly1305::{aead::{Aead, OsRng}, AeadCore, KeyInit, XChaCha20Poly1305, XNonce};
use hex::{encode, decode};
use log::debug;
pub fn encrypt(key: &Vec<u8>, plaintext: String)->Result<String>{
let cipher = XChaCha20Poly1305::new_from_slice(&key)?;
let nonce = XChaCha20Poly1305::generate_nonce(&mut OsRng);
let ciphertext = match cipher.encrypt(&nonce, plaintext.as_bytes()){
Ok(v) => Ok(v),
Err(e) => Err(anyhow!("failed to encrypt because {}", e.to_string())),
}?;
println!("{}",encode(nonce));
Ok(encode(nonce) + &encode(ciphertext))
}
pub fn decrypt(key: &Vec<u8>, ciphertext: String) -> Result<String>{
let cipher = XChaCha20Poly1305::new_from_slice(&key)?;
let mut iter = ciphertext.char_indices();
let (start, _) = iter.nth(0).ok_or(anyhow!("Cannot find 0 index"))?;
let (end, _) = iter.nth(47).ok_or(anyhow!("Cannot find end of nonce"))?;
let nonce_string = &ciphertext[start..end];
debug!("{}, {}", nonce_string.len(), nonce_string);
let nonce = XNonce::from_iter(decode(nonce_string)?.into_iter());
let remaining = &ciphertext[end..ciphertext.len()];
let decoded = decode(remaining)?;
let plaintext = match cipher.decrypt(&nonce, decoded.as_ref()){
Ok(p) => {
Ok(str::from_utf8(&p)?.to_string())
},
Err(e) => Err(anyhow!("Decrypt error {}", e.to_string())),
}?;
Ok(plaintext)
}
}
pub mod hash{
use anyhow::Result;
use hmac::{Hmac, Mac};
use sha2::Sha256;
type HmacSha256 = Hmac<Sha256>;
pub fn prf(key: &Vec<u8>, plaintext: String) -> Result<String>{
let mut mac = HmacSha256::new_from_slice(&key)?;
mac.update(&plaintext.into_bytes());
// let result = ;
Ok(hex::encode(mac.finalize().into_bytes()))
}
// let mut mac = HmacSha256::new_from_slice(b"my secret and secure key")
......
......@@ -3,7 +3,7 @@ use std::collections::HashMap;
use csv::Reader;
mod crypto;
use anyhow::{Result, anyhow};
use crypto::{keys::load_credentials, hash::prf};
use crypto::{chacha::{decrypt, encrypt}, hash::prf, keys::load_credentials};
mod commandline;
use commandline::{Cli, Commands};
......@@ -97,7 +97,13 @@ fn upload(filepath: &Path, key: Option<String>, index_o: Option<usize>) -> Resul
while let Some(result) = reader.records().next(){
let record = result?;
// hm.insert(record.get(index).unwrap().to_string(), record.iter().map(|x| x.to_string() + ",").collect::<String>());
println!("{:?}", prf(&prf_key, record.get(index).ok_or(anyhow!("Failed to get element"))?.to_string()))
println!("{:?}", prf(&prf_key, record.get(index).ok_or(anyhow!("Failed to get element"))?.to_string()));
let l = record.iter().collect::<Vec<&str>>().join(",");
let encrypted = encrypt(&enc_key, l)?;
println!("{}", decrypt(&enc_key, encrypted)?);
let mut line = String::new();
let _ = std::io::stdin().read_line(&mut line).unwrap();
}
Ok(())
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment