39 lines
1.1 KiB
Rust
39 lines
1.1 KiB
Rust
use argon2::password_hash::rand_core::OsRng;
|
|
use argon2::password_hash::SaltString;
|
|
use argon2::{Argon2, PasswordHash, PasswordHasher, PasswordVerifier};
|
|
|
|
/// Verifies that the given password matches the given hash.
|
|
pub fn verify(hash: &str, password: &str) -> bool {
|
|
let parsed_hash = match PasswordHash::new(hash) {
|
|
Ok(hash) => hash,
|
|
Err(_) => return false, // TODO: log an error
|
|
};
|
|
|
|
Argon2::default().verify_password(password.as_bytes(), &parsed_hash).is_ok()
|
|
}
|
|
|
|
/// Hashes the given password.
|
|
pub fn hash(password: &str) -> String {
|
|
let salt = SaltString::generate(&mut OsRng);
|
|
|
|
let hash = Argon2::default().hash_password(password.as_bytes(), &salt).unwrap();
|
|
|
|
hash.to_string()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_password_hashes_match() {
|
|
// this is a well-known example password:
|
|
// https://knowyourmeme.com/memes/hunter2
|
|
let password = "hunter2";
|
|
let hashed_password = hash(password);
|
|
let hashed_other = hash("not-the-password");
|
|
|
|
assert!(verify(&hashed_password, password));
|
|
assert!(!verify(&hashed_other, password));
|
|
}
|
|
}
|