geekorm_core/utils/crypto/
hashing.rs1#[cfg(feature = "hash-argon2")]
2use argon2::Argon2;
3#[cfg(feature = "hash-pbkdf2")]
4use pbkdf2::Pbkdf2;
5#[cfg(feature = "hash-sha512")]
6use sha_crypt::{Sha512Params, sha512_check, sha512_simple};
7use password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString, rand_core::OsRng};
9
10use crate::utils::crypto::HashingAlgorithm;
11
12#[allow(unreachable_patterns)]
14pub fn generate_hash(data: String, alg: HashingAlgorithm) -> Result<String, crate::Error> {
15 match alg {
16 #[cfg(feature = "hash-pbkdf2")]
17 HashingAlgorithm::Pbkdf2 => generate_hash_pdkdf2(data),
18 #[cfg(feature = "hash-argon2")]
19 HashingAlgorithm::Argon2 => generate_hash_argon2(data),
20 #[cfg(feature = "hash-sha512")]
21 HashingAlgorithm::Sha512 => generate_hash_sha512(data),
22 _ => Err(crate::Error::HashingError(
23 "Invalid hashing algorithm".to_string(),
24 )),
25 }
26}
27
28#[cfg(feature = "hash")]
43pub fn verify_hash(
44 data: String,
45 hash: String,
46 alg: HashingAlgorithm,
47) -> Result<bool, crate::Error> {
48 match alg {
49 HashingAlgorithm::Pbkdf2 => verify_hash_pbkdf2(data, hash),
50 #[cfg(feature = "hash-argon2")]
51 HashingAlgorithm::Argon2 => {
52 let hasher = PasswordHash::new(&hash).map_err(|e| {
53 crate::Error::HashingError(format!("Error parsing password hash: {}", e))
54 })?;
55 match Argon2::default().verify_password(data.as_bytes(), &hasher) {
56 Ok(_) => Ok(true),
57 Err(_) => Ok(false),
58 }
59 }
60 #[cfg(feature = "hash-sha512")]
61 HashingAlgorithm::Sha512 => match sha512_check(data.as_str(), hash.as_str()) {
62 Ok(_) => Ok(true),
63 Err(_) => Ok(false),
64 },
65 }
66}
67
68#[cfg(feature = "hash")]
70pub(crate) fn generate_hash_pdkdf2(data: String) -> Result<String, crate::Error> {
71 let salt = SaltString::generate(&mut OsRng);
73 match Pbkdf2.hash_password(data.as_bytes(), &salt) {
75 Ok(hash) => Ok(hash.to_string()),
76 Err(e) => Err(crate::Error::HashingError(format!(
77 "Error hashing password: {}",
78 e
79 ))),
80 }
81}
82
83#[cfg(feature = "hash")]
84pub(crate) fn verify_hash_pbkdf2(data: String, hash: String) -> Result<bool, crate::Error> {
85 let parsed_hash = match PasswordHash::new(&hash) {
86 Ok(h) => h,
87 Err(e) => {
88 return Err(crate::Error::HashingError(format!(
89 "Error parsing password hash: {}",
90 e
91 )));
92 }
93 };
94
95 match Pbkdf2.verify_password(data.as_bytes(), &parsed_hash) {
96 Ok(_) => Ok(true),
97 Err(_) => Ok(false),
98 }
99}
100
101#[cfg(feature = "hash-argon2")]
103pub(crate) fn generate_hash_argon2(data: String) -> Result<String, crate::Error> {
104 let salt = SaltString::generate(&mut OsRng);
106 let argon2 = Argon2::default();
108
109 match argon2.hash_password(data.as_bytes(), &salt) {
110 Ok(hash) => Ok(hash.to_string()),
111 Err(e) => Err(crate::Error::HashingError(format!(
112 "Error hashing password: {}",
113 e
114 ))),
115 }
116}
117
118#[cfg(feature = "hash-sha512")]
120pub(crate) fn generate_hash_sha512(data: String) -> Result<String, crate::Error> {
121 let params = match Sha512Params::new(100_000) {
122 Ok(p) => p,
123 Err(_) => {
124 return Err(crate::Error::HashingError(String::from(
125 "Error creating params for sha512",
126 )));
127 }
128 };
129 match sha512_simple(data.as_str(), ¶ms) {
130 Ok(hash) => Ok(hash),
131 Err(_) => Err(crate::Error::HashingError(
132 "Error hashing password using SHA512".to_string(),
133 )),
134 }
135}