mirror of
https://github.com/danbulant/Portfolio
synced 2026-05-24 20:42:15 +00:00
feat: age key encryption
This commit is contained in:
parent
0a7b0c9028
commit
7623bc80c2
1 changed files with 74 additions and 17 deletions
|
|
@ -1,3 +1,5 @@
|
|||
use std::str::FromStr;
|
||||
use std::iter;
|
||||
use argon2::{
|
||||
Argon2, PasswordHasher as ArgonPasswordHasher, PasswordVerifier as ArgonPasswordVerifier,
|
||||
};
|
||||
|
|
@ -27,18 +29,19 @@ pub fn random_8_char_string() -> String {
|
|||
|
||||
// TODO: No unwrap for spawn_blocking
|
||||
pub async fn hash_password(
|
||||
password_plaint_text: String,
|
||||
password_plain_text: String,
|
||||
) -> Result<String, argon2::password_hash::Error> {
|
||||
let argon_config = Argon2::default();
|
||||
|
||||
let hash = tokio::task::spawn_blocking(move || {
|
||||
let password = password_plaint_text.as_bytes();
|
||||
let password = password_plain_text.as_bytes();
|
||||
let salt = "c2VjcmV0bHl0ZXN0aW5nZXZlcnl0aGluZw";
|
||||
|
||||
let encrypted = argon_config.hash_password(password, salt);
|
||||
encrypted
|
||||
})
|
||||
.await.unwrap();
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let result = hash?;
|
||||
|
||||
|
|
@ -52,25 +55,26 @@ pub async fn verify_password<'a>(
|
|||
) -> Result<bool, argon2::password_hash::Error> {
|
||||
let argon_config = Argon2::default();
|
||||
|
||||
let result: Result<bool, argon2::password_hash::Error> = tokio::task::spawn_blocking(move || {
|
||||
let parsed_hash = argon2::PasswordHash::new(&hash);
|
||||
match parsed_hash {
|
||||
Ok(parsed) => {
|
||||
return Ok(argon_config
|
||||
.verify_password(password_plaint_text.as_bytes(), &parsed)
|
||||
.is_ok())
|
||||
let result: Result<bool, argon2::password_hash::Error> =
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let parsed_hash = argon2::PasswordHash::new(&hash);
|
||||
match parsed_hash {
|
||||
Ok(parsed) => {
|
||||
return Ok(argon_config
|
||||
.verify_password(password_plaint_text.as_bytes(), &parsed)
|
||||
.is_ok())
|
||||
}
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub async fn encrypt_password(
|
||||
password_plaint_text: &str,
|
||||
password_plain_text: &str,
|
||||
key: &str,
|
||||
) -> Result<String, age::EncryptError> {
|
||||
let encryptor = age::Encryptor::with_user_passphrase(age::secrecy::Secret::new(key.to_owned()));
|
||||
|
|
@ -79,7 +83,7 @@ pub async fn encrypt_password(
|
|||
let mut encrypt_writer = encryptor.wrap_async_output(&mut encrypt_buffer).await?;
|
||||
|
||||
encrypt_writer
|
||||
.write_all(password_plaint_text.as_bytes())
|
||||
.write_all(password_plain_text.as_bytes())
|
||||
.await?;
|
||||
|
||||
encrypt_writer.flush().await?;
|
||||
|
|
@ -108,3 +112,56 @@ pub async fn decrypt_password(
|
|||
|
||||
Ok(String::from_utf8(decrypt_buffer)?)
|
||||
}
|
||||
|
||||
pub async fn encrypt_password_with_recipients(
|
||||
password_plain_text: &str,
|
||||
recipients: Vec<&str>,
|
||||
) -> Result<String, age::EncryptError> {
|
||||
let public_keys = recipients
|
||||
.into_iter()
|
||||
.map(|recipient| {
|
||||
//TODO: No unwrap
|
||||
Box::new(age::x25519::Recipient::from_str(recipient).unwrap()) as _
|
||||
})
|
||||
.collect();
|
||||
|
||||
let encryptor_option = age::Encryptor::with_recipients(public_keys);
|
||||
|
||||
if let Some(encryptor) = encryptor_option {
|
||||
let mut encrypt_buffer = Vec::new();
|
||||
let mut encrypt_writer = encryptor.wrap_async_output(&mut encrypt_buffer).await?;
|
||||
|
||||
encrypt_writer
|
||||
.write_all(password_plain_text.as_bytes())
|
||||
.await?;
|
||||
|
||||
encrypt_writer.flush().await?;
|
||||
|
||||
encrypt_writer.close().await?;
|
||||
|
||||
Ok(base64::encode(encrypt_buffer))
|
||||
} else {
|
||||
// TODO: Error handling
|
||||
unreachable!("No recipients provided");
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn decrypt_password_with_private_key(
|
||||
password_encrypted: &str,
|
||||
key: &str,
|
||||
) -> Result<String, Box<dyn std::error::Error>> {
|
||||
let encrypted = base64::decode(password_encrypted)?;
|
||||
|
||||
let decryptor = match age::Decryptor::new_async(&encrypted[..]).await? {
|
||||
age::Decryptor::Recipients(d) => d,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut decrypt_buffer = Vec::new();
|
||||
let mut decrypt_writer =
|
||||
decryptor.decrypt_async(iter::once(&age::x25519::Identity::from_str(key)? as &dyn age::Identity))?;
|
||||
|
||||
decrypt_writer.read_to_end(&mut decrypt_buffer).await?;
|
||||
|
||||
Ok(String::from_utf8(decrypt_buffer)?)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue