diff --git a/core/Cargo.toml b/core/Cargo.toml index ad9a9b0..33a247d 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -7,10 +7,16 @@ edition = "2021" serde = { version = "1.0", features = ["derive"] } portfolio-entity = { path = "../entity" } rand = "0.8.5" -argon2 = "0.4.1" chrono = "0.4.22" jsonwebtoken = "8.1.1" dotenv = "0.15.0" +tokio = "1.21.2" +futures = "0.3.25" + +# crypto +argon2 = "0.4.1" +age = { version = "0.9.0", features = ["async"] } +base64 = "0.13.1" [dependencies.sea-orm] version = "^0.10.0" diff --git a/core/src/crypto.rs b/core/src/crypto.rs index e0562c0..63cb1e5 100644 --- a/core/src/crypto.rs +++ b/core/src/crypto.rs @@ -1,4 +1,4 @@ -use std::io::{Write, Read}; +use futures::io::{AsyncReadExt, AsyncWriteExt}; use argon2::{ Argon2, PasswordHasher as ArgonPasswordHasher, PasswordVerifier as ArgonPasswordVerifier, }; @@ -29,53 +29,56 @@ pub fn random_8_char_string() -> String { s } -pub fn hash_password(password_plaint_text: &str) -> Result { - let password = password_plaint_text.as_bytes(); - let salt = "c2VjcmV0bHl0ZXN0aW5nZXZlcnl0aGluZw"; - +pub async fn hash_password(password_plaint_text: String) -> Result { let argon_config = Argon2::default(); - let hash = argon_config.hash_password(password, salt)?; + let hash = tokio::task::spawn_blocking(move || { + let password = password_plaint_text.as_bytes(); + let salt = "c2VjcmV0bHl0ZXN0aW5nZXZlcnl0aGluZw"; + + let encrypted = argon_config.hash_password(password, salt); + encrypted + }).await; - return Ok(hash.to_string()); + let result = hash.unwrap()?; + + return Ok(result.to_string()); } -// TODO: Async? Zatím pod spawn_blocking -pub fn encrypt_password(password_plaint_text: &str, key: &str) -> Result { +pub async fn encrypt_password(password_plaint_text: &str, key: &str) -> Result { let encryptor = age::Encryptor::with_user_passphrase(age::secrecy::Secret::new(key.to_owned())); let mut encrypt_buffer = Vec::new(); - let mut encrypt_writer = encryptor.wrap_output(&mut encrypt_buffer)?; + let mut encrypt_writer = encryptor.wrap_async_output(&mut encrypt_buffer).await?; - encrypt_writer.write_all(password_plaint_text.as_bytes())?; + encrypt_writer.write_all(password_plaint_text.as_bytes()).await?; - encrypt_writer.finish()?; + encrypt_writer.flush().await?; + + encrypt_writer.close().await?; - Ok(base64::encode(encrypt_buffer)) } -pub fn decrypt_password( +pub async fn decrypt_password( password_encrypted: &str, key: &str, ) -> Result> { let encrypted = base64::decode(password_encrypted)?; - let decryptor = match age::Decryptor::new(&encrypted[..])? { + let decryptor = match age::Decryptor::new_async(&encrypted[..]).await? { age::Decryptor::Passphrase(d) => d, _ => unreachable!(), }; let mut decrypt_buffer = Vec::new(); - let mut decrypt_writer = decryptor.decrypt(&age::secrecy::Secret::new(key.to_owned()), None)?; + let mut decrypt_writer = decryptor.decrypt_async(&age::secrecy::Secret::new(key.to_owned()), None)?; - decrypt_writer.read_to_end(&mut decrypt_buffer)?; + decrypt_writer.read_to_end(&mut decrypt_buffer).await?; Ok(String::from_utf8(decrypt_buffer)?) } - - pub fn verify_password( password_plaint_text: &str, hash: &str,