webgates_secrets/hashing.rs
1//! Password hashing and verification APIs.
2//!
3//! This module contains the hashing-facing API of `webgates-secrets`.
4//!
5//! It provides the hashing abstraction, the default Argon2id implementation,
6//! and the [`HashedValue`] type used for stored hashes.
7//!
8//! # Key types
9//!
10//! - [`hashing_service::HashingService`] for hashing and verification
11//! - [`HashedValue`] for persisted hash strings
12//! - [`argon2`] for the default Argon2id implementation
13//!
14//! # Examples
15//!
16//! ```rust
17//! use webgates_core::verification_result::VerificationResult;
18//! use webgates_secrets::hashing::argon2::Argon2Hasher;
19//! use webgates_secrets::hashing::hashing_service::HashingService;
20//!
21//! let hasher = Argon2Hasher::new_recommended().unwrap();
22//!
23//! // Hash a password
24//! let hashed = hasher.hash_value("user_password").unwrap();
25//! println!("Hashed password: {}", hashed);
26//!
27//! // Verify a password
28//! let result = hasher.verify_value("user_password", &hashed).unwrap();
29//! assert_eq!(result, VerificationResult::Ok);
30//! ```
31//!
32//! # Canonical Public Paths
33//!
34//! Each public item in this module has a single canonical path through its owning
35//! submodule:
36//!
37//! - [`crate::hashing::argon2::Argon2Hasher`]
38//! - [`crate::hashing::hashing_service::HashingService`]
39//! - [`crate::hashing::errors::HashingError`]
40//! - [`crate::hashing::errors::HashingOperation`]
41//! - [`crate::hashing::HashedValue`]
42//!
43//! # Security notes
44//!
45//! - **Argon2id algorithm** - Recommended by password hashing competition
46//! - **Configurable parameters** - Memory cost, time cost, and parallelism
47//! - **Built-in salt generation** - Each password gets a unique random salt
48//! - **Constant-time verification** - Prevents timing attacks
49//! - **Development vs production profiles** - Fast hashing in debug builds, secure in release
50//!
51//! # Usage notes
52//!
53//! The hashing service automatically adjusts parameters based on build configuration:
54//! - **Debug builds**: Fast parameters for development efficiency
55//! - **Release builds**: Secure parameters for production security
56//! - **Custom parameters**: Override via `Argon2Hasher::from_config()`
57
58pub mod argon2;
59pub mod errors;
60/// Hashing service traits and public contracts.
61///
62/// Use the canonical path [`crate::hashing::hashing_service::HashingService`]
63/// to import the hashing trait.
64pub mod hashing_service;
65
66/// Stored hash string produced by a hashing algorithm.
67///
68/// This is the persisted representation returned by hashing implementations.
69/// It usually contains the algorithm identifier, parameters, salt, and hash in
70/// a standardized format.
71///
72/// # Format
73///
74/// For Argon2id hashes, the format follows the PHC (Password Hashing Competition) standard:
75/// ```text
76/// $argon2id$v=19$m=65536,t=3,p=1$<salt>$<hash>
77/// ```
78///
79/// Where:
80/// - `argon2id` - Algorithm identifier
81/// - `v=19` - Algorithm version
82/// - `m=65536,t=3,p=1` - Memory cost, time cost, parallelism parameters
83/// - `<salt>` - Base64-encoded random salt
84/// - `<hash>` - Base64-encoded password hash
85///
86/// # Security notes
87///
88/// - **Self-contained**: Includes all information needed for verification
89/// - **Salt included**: Each hash has a unique random salt to prevent rainbow table attacks
90/// - **Parameter embedded**: Hash contains the parameters used, enabling verification
91/// - **Future-proof**: Format supports algorithm upgrades and parameter changes
92///
93/// # Examples
94///
95/// ```rust
96/// use webgates_secrets::hashing::argon2::Argon2Hasher;
97/// use webgates_secrets::hashing::hashing_service::HashingService;
98/// use webgates_secrets::hashing::HashedValue;
99///
100/// let hasher = Argon2Hasher::new_recommended().unwrap();
101/// let hashed: HashedValue = hasher.hash_value("my_password").unwrap();
102///
103/// // The hashed value is self-contained and can be stored directly
104/// println!("Hashed password: {}", hashed);
105///
106/// // Later, verify against the stored hash
107/// use webgates_core::verification_result::VerificationResult;
108/// let result = hasher.verify_value("my_password", &hashed).unwrap();
109/// assert_eq!(result, VerificationResult::Ok);
110/// ```
111///
112/// # Usage notes
113///
114/// - **Database storage**: Store as TEXT/VARCHAR with sufficient length (≥100 characters recommended)
115/// - **No additional encoding needed**: The string is already in a safe, printable format
116/// - **Indexing**: Generally should not be indexed as hashes are not used for lookups
117/// - **Migration**: Hash format changes require re-hashing passwords during user login
118pub type HashedValue = String;