Skip to main content

cas_lib/password_hashers/
scrypt.rs

1
2
3
4
5
6use scrypt::{
7    password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
8    Scrypt, Params
9};
10
11use crate::error::{CasError, CasResult};
12
13pub struct CASScrypt;
14
15impl CASScrypt {
16    /// Hashes a passwith using Scrypt with custom params.
17    /// Parameters:
18    /// - password_to_hash: The password to be hashed.
19    /// - cpu_memory_cost: logâ‚‚ of the Scrypt parameter `N`, the work factor.
20    /// - block_size: `r` parameter: resource usage.
21    /// - parallelism: `p` parameter: parallelization.
22    pub fn hash_password_customized(password_to_hash: String, cpu_memory_cost: u8, block_size: u32, parallelism: u32) -> CasResult<String> {
23        let salt = SaltString::generate(&mut OsRng);
24        let params = Params::new(cpu_memory_cost, block_size, parallelism, 32)
25            .map_err(|_| CasError::InvalidParameters)?;
26        Ok(Scrypt
27            .hash_password_customized(password_to_hash.as_bytes(), None, None, params, &salt)
28            .map_err(|_| CasError::PasswordHashingFailed)?
29            .to_string())
30    }
31
32    /// Hashes a password using Scrypt.
33    /// Returns the hashed password as a string.
34    pub fn hash_password(password_to_hash: String) -> CasResult<String> {
35        let salt = SaltString::generate(&mut OsRng);
36        Ok(Scrypt
37            .hash_password(password_to_hash.as_bytes(), &salt)
38            .map_err(|_| CasError::PasswordHashingFailed)?
39            .to_string())
40    }
41
42    /// Verifies a password against a hashed password using Scrypt.
43    /// Returns `Ok(true)` if the password matches, `Ok(false)` if it does not, and
44    /// an error if the stored hash could not be parsed.
45    pub fn verify_password(hashed_password: String, password_to_verify: String) -> CasResult<bool> {
46        let parsed_hash =
47            PasswordHash::new(&hashed_password).map_err(|_| CasError::PasswordHashingFailed)?;
48        Ok(Scrypt
49            .verify_password(password_to_verify.as_bytes(), &parsed_hash)
50            .is_ok())
51    }
52}