1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! Password hashing and secure token generation.
//!
//! Enabled by the `crypto` Cargo feature:
//!
//! ```toml
//! rust-web-server = { version = "17", features = ["crypto"] }
//! ```
//!
//! # Password hashing
//!
//! Uses Argon2id (OWASP recommended) with a random 128-bit salt. The output
//! is a self-describing PHC string that includes the algorithm, parameters,
//! salt, and hash — store it as-is in your database.
//!
//! ```rust
//! use rust_web_server::crypto::{hash_password, verify_password};
//!
//! let hash = hash_password("hunter2").unwrap();
//! assert!(verify_password("hunter2", &hash).unwrap());
//! assert!(!verify_password("wrong", &hash).unwrap());
//! ```
//!
//! # Secure token generation
//!
//! ```rust
//! use rust_web_server::crypto::generate_token;
//!
//! let token = generate_token(32); // 32 random bytes → 64-char lowercase hex string
//! ```
use ;
use ;
/// Error returned by crypto operations.
;
/// Hash `password` using Argon2id with a random salt.
///
/// Returns a PHC string (`$argon2id$v=19$...`) suitable for storing in a
/// database. The salt is embedded in the string — no separate storage needed.
///
/// # Errors
///
/// Returns `CryptoError` if the hashing operation fails (extremely unlikely
/// with valid inputs).
/// Verify `password` against a PHC hash string produced by [`hash_password`].
///
/// Returns `Ok(true)` if the password matches, `Ok(false)` if it does not.
/// Comparison is constant-time to prevent timing attacks.
///
/// # Errors
///
/// Returns `CryptoError` if `hash` is not a valid PHC string.
/// Generate `n_bytes` of cryptographically secure random bytes and return them
/// as a lowercase hex string of length `n_bytes * 2`.
///
/// Suitable for password-reset tokens, email verification codes, and API keys.
/// Use at least 16 bytes (32 hex chars) for tokens; 32 bytes (64 hex chars) for
/// high-value secrets like API keys.