|
21 | 21 | //! |
22 | 22 | //! [KDF]: https://github.com/RustCrypto/KDFs |
23 | 23 | //! |
| 24 | +//! ## Low-level API |
| 25 | +//! |
| 26 | +//! This API operates directly on byte slices: |
| 27 | +//! |
24 | 28 | //! ``` |
25 | 29 | //! # #[cfg(feature = "hmac")] { |
26 | 30 | //! use hex_literal::hex; |
|
57 | 61 | //! rand_core = { version = "0.6", features = ["std"] } |
58 | 62 | //! ``` |
59 | 63 | //! |
| 64 | +//! ## PHC string API |
| 65 | +//! |
| 66 | +//! This crate can produce and verify password hash strings encoded in the Password Hashing |
| 67 | +//! Competition (PHC) string format. |
| 68 | +//! |
60 | 69 | //! The following example demonstrates the high-level password hashing API: |
61 | 70 | //! |
62 | | -#![cfg_attr(feature = "password-hash", doc = "```")] |
63 | | -#![cfg_attr(not(feature = "password-hash"), doc = "```ignore")] |
| 71 | +#![cfg_attr(all(feature = "getrandom", feature = "phc"), doc = "```")] |
| 72 | +#![cfg_attr(not(all(feature = "getrandom", feature = "phc")), doc = "```ignore")] |
64 | 73 | //! # fn main() -> Result<(), Box<dyn core::error::Error>> { |
65 | 74 | //! // NOTE: example requires `getrandom` feature is enabled |
66 | 75 | //! |
67 | 76 | //! use pbkdf2::{ |
68 | | -//! password_hash::{PasswordHasher, PasswordVerifier, phc::PasswordHash}, |
| 77 | +//! password_hash::{PasswordHasher, PasswordVerifier}, |
| 78 | +//! phc::PasswordHash, |
69 | 79 | //! Pbkdf2 |
70 | 80 | //! }; |
71 | 81 | //! |
72 | 82 | //! let pbkdf2 = Pbkdf2::default(); // Uses `Algorithm::default()` and `Params::RECOMMENDED` |
73 | 83 | //! let password = b"hunter2"; // Bad password; don't actually use! |
74 | 84 | //! |
75 | 85 | //! // Hash password to PHC string ($pbkdf2-sha256$...) |
76 | | -//! let password_hash = pbkdf2.hash_password(password)?.to_string(); |
| 86 | +//! let pwhash: PasswordHash = pbkdf2.hash_password(password)?; |
| 87 | +//! let pwhash_string = pwhash.to_string(); |
77 | 88 | //! |
78 | 89 | //! // Verify password against PHC string |
79 | | -//! let parsed_hash = PasswordHash::new(&password_hash)?; |
80 | | -//! assert!(pbkdf2.verify_password(password, &parsed_hash).is_ok()); |
| 90 | +//! let parsed_hash = PasswordHash::new(&pwhash_string)?; |
| 91 | +//! pbkdf2.verify_password(password, &parsed_hash)?; |
81 | 92 | //! # Ok(()) |
82 | 93 | //! # } |
83 | 94 | //! ``` |
84 | 95 |
|
85 | | -#[cfg(feature = "password-hash")] |
86 | | -extern crate alloc; |
87 | | - |
88 | | -#[cfg(feature = "password-hash")] |
89 | | -pub use password_hash; |
| 96 | +#[cfg(feature = "mcf")] |
| 97 | +pub mod mcf; |
| 98 | +#[cfg(feature = "phc")] |
| 99 | +pub mod phc; |
90 | 100 |
|
91 | | -#[cfg(feature = "password-hash")] |
| 101 | +#[cfg(any(feature = "mcf", feature = "phc"))] |
92 | 102 | mod algorithm; |
93 | | -#[cfg(feature = "password-hash")] |
| 103 | +#[cfg(any(feature = "mcf", feature = "phc"))] |
94 | 104 | mod params; |
95 | | -#[cfg(feature = "password-hash")] |
96 | | -mod phc; |
97 | 105 |
|
| 106 | +#[cfg(any(feature = "mcf", feature = "phc"))] |
| 107 | +pub use crate::{algorithm::Algorithm, params::Params}; |
98 | 108 | #[cfg(feature = "hmac")] |
99 | 109 | pub use hmac; |
100 | | - |
101 | | -#[cfg(feature = "password-hash")] |
102 | | -pub use crate::{algorithm::Algorithm, params::Params, phc::Pbkdf2}; |
| 110 | +#[cfg(any(feature = "mcf", feature = "phc"))] |
| 111 | +pub use password_hash; |
103 | 112 |
|
104 | 113 | use digest::{FixedOutput, InvalidLength, KeyInit, Update, typenum::Unsigned}; |
105 | 114 |
|
@@ -242,3 +251,42 @@ where |
242 | 251 | pbkdf2_hmac::<D>(password, salt, rounds, &mut buf); |
243 | 252 | buf |
244 | 253 | } |
| 254 | + |
| 255 | +/// PBKDF2 type for use with [`PasswordHasher`]. |
| 256 | +#[cfg(any(feature = "mcf", feature = "phc"))] |
| 257 | +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] |
| 258 | +pub struct Pbkdf2 { |
| 259 | + /// Algorithm to use |
| 260 | + algorithm: Algorithm, |
| 261 | + |
| 262 | + /// Default parameters to use. |
| 263 | + params: Params, |
| 264 | +} |
| 265 | + |
| 266 | +#[cfg(any(feature = "mcf", feature = "phc"))] |
| 267 | +impl Pbkdf2 { |
| 268 | + /// Initialize [`Pbkdf2`] with default parameters. |
| 269 | + pub const fn new(algorithm: Algorithm, params: Params) -> Self { |
| 270 | + Self { algorithm, params } |
| 271 | + } |
| 272 | +} |
| 273 | + |
| 274 | +#[cfg(any(feature = "mcf", feature = "phc"))] |
| 275 | +impl From<Algorithm> for Pbkdf2 { |
| 276 | + fn from(algorithm: Algorithm) -> Self { |
| 277 | + Self { |
| 278 | + algorithm, |
| 279 | + params: Params::default(), |
| 280 | + } |
| 281 | + } |
| 282 | +} |
| 283 | + |
| 284 | +#[cfg(any(feature = "mcf", feature = "phc"))] |
| 285 | +impl From<Params> for Pbkdf2 { |
| 286 | + fn from(params: Params) -> Self { |
| 287 | + Self { |
| 288 | + algorithm: Algorithm::default(), |
| 289 | + params, |
| 290 | + } |
| 291 | + } |
| 292 | +} |
0 commit comments