mirror of
https://github.com/rust-lang-nursery/rust-cookbook
synced 2024-11-24 20:43:07 +00:00
Adds recipe for salt and hash a password using ring crate
* Uses PBKDF2 key derivation function * Verifies password with hash
This commit is contained in:
parent
b2701a4486
commit
45b785788d
2 changed files with 83 additions and 0 deletions
|
@ -20,6 +20,7 @@
|
|||
| [Extract phone numbers from text][ex-phone] | [![regex-badge]][regex] | [![cat-text-processing-badge]][cat-text-processing] |
|
||||
| [Calculate the SHA-256 digest of a file][ex-sha-digest] | [![ring-badge]][ring] [![data-encoding-badge]][data-encoding] | [![cat-cryptography-badge]][cat-cryptography] |
|
||||
| [Sign and verify a message with an HMAC digest][ex-hmac] | [![ring-badge]][ring] | [![cat-cryptography-badge]][cat-cryptography] |
|
||||
| [Salt and hash a password with PBKDF2][ex-pbkdf2] | [![ring-badge]][ring] [![data-encoding-badge]][data-encoding] | [![cat-cryptography-badge]][cat-cryptography] |
|
||||
| [Define and operate on a type represented as a bitfield][ex-bitflags] | [![bitflags-badge]][bitflags] | [![cat-no-std-badge]][cat-no-std] |
|
||||
| [Access a file randomly using a memory map][ex-random-file-access] | [![memmap-badge]][memmap] | [![cat-filesystem-badge]][cat-filesystem] |
|
||||
| [Check number of logical cpu cores][ex-check-cpu-cores] | [![num_cpus-badge]][num_cpus] | [![cat-hardware-support-badge]][cat-hardware-support] |
|
||||
|
@ -900,6 +901,82 @@ fn run() -> Result<()> {
|
|||
# quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-pbkdf2]: #ex-pbkdf2
|
||||
<a name="ex-pbkdf2"></a>
|
||||
## Salt and hash a password with PBKDF2
|
||||
|
||||
[![ring-badge]][ring] [![data-encoding-badge]][data-encoding] [![cat-cryptography-badge]][cat-cryptography]
|
||||
|
||||
Uses [`ring::pbkdf2`] to hash a salted password using the PBKDF2 key derivation
|
||||
function [`pbkdf2::derive`] and then verifies the hash is correct with
|
||||
[`pbkdf2::verify`]. The salt is generated using
|
||||
[`SecureRandom::fill`], which fills the salt byte array with
|
||||
securely generated random numbers.
|
||||
|
||||
```rust
|
||||
# #[macro_use]
|
||||
# extern crate error_chain;
|
||||
extern crate data_encoding;
|
||||
extern crate ring;
|
||||
#
|
||||
# error_chain! {
|
||||
# foreign_links {
|
||||
# Ring(ring::error::Unspecified);
|
||||
# }
|
||||
# }
|
||||
|
||||
use data_encoding::HEXUPPER;
|
||||
use ring::{digest, pbkdf2, rand};
|
||||
use ring::rand::SecureRandom;
|
||||
|
||||
fn run() -> Result<()> {
|
||||
const CREDENTIAL_LEN: usize = digest::SHA512_OUTPUT_LEN;
|
||||
const N_ITER: u32 = 100_000;
|
||||
let rng = rand::SystemRandom::new();
|
||||
|
||||
// Generate salt
|
||||
let mut salt = [0u8; CREDENTIAL_LEN];
|
||||
rng.fill(&mut salt)?;
|
||||
|
||||
// Hash password
|
||||
let password = "Guess Me If You Can!";
|
||||
let mut pbkdf2_hash = [0u8; CREDENTIAL_LEN];
|
||||
pbkdf2::derive(
|
||||
&digest::SHA512,
|
||||
N_ITER,
|
||||
&salt,
|
||||
password.as_bytes(),
|
||||
&mut pbkdf2_hash,
|
||||
);
|
||||
println!("Salt: {}", HEXUPPER.encode(&salt));
|
||||
println!("PBKDF2 hash: {}", HEXUPPER.encode(&pbkdf2_hash));
|
||||
|
||||
// Verify hash with correct password and wrong password
|
||||
let should_succeed = pbkdf2::verify(
|
||||
&digest::SHA512,
|
||||
N_ITER,
|
||||
&salt,
|
||||
password.as_bytes(),
|
||||
&pbkdf2_hash,
|
||||
);
|
||||
let wrong_password = "Definitely not the correct password";
|
||||
let should_fail = pbkdf2::verify(
|
||||
&digest::SHA512,
|
||||
N_ITER,
|
||||
&salt,
|
||||
wrong_password.as_bytes(),
|
||||
&pbkdf2_hash,
|
||||
);
|
||||
|
||||
assert!(should_succeed.is_ok());
|
||||
assert!(!should_fail.is_ok());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
#
|
||||
# quick_main!(run);
|
||||
```
|
||||
|
||||
[ex-bitflags]: #ex-bitflags
|
||||
<a name="ex-bitflags"></a>
|
||||
## Define and operate on a type represented as a bitfield
|
||||
|
@ -1050,6 +1127,8 @@ fn main() {
|
|||
[`Normal`]: https://doc.rust-lang.org/rand/rand/distributions/normal/struct.Normal.html
|
||||
[`num_cpus::get`]: https://docs.rs/num_cpus/*/num_cpus/fn.get.html
|
||||
[`Output`]: https://doc.rust-lang.org/std/process/struct.Output.html
|
||||
[`pbkdf2::derive`]: https://docs.rs/ring/*/ring/pbkdf2/fn.derive.html
|
||||
[`pbkdf2::verify`]: https://docs.rs/ring/*/ring/pbkdf2/fn.verify.html
|
||||
[`rand::Rand`]: https://doc.rust-lang.org/rand/rand/trait.Rand.html
|
||||
[`rand::Rand`]: https://doc.rust-lang.org/rand/rand/trait.Rand.html
|
||||
[`rand::Rng`]: https://doc.rust-lang.org/rand/rand/trait.Rng.html
|
||||
|
@ -1061,8 +1140,10 @@ fn main() {
|
|||
[`regex::RegexSetBuilder`]: https://doc.rust-lang.org/regex/regex/struct.RegexSetBuilder.html
|
||||
[`Regex::replace_all`]: https://docs.rs/regex/*/regex/struct.Regex.html#method.replace_all
|
||||
[`Regex`]: https://doc.rust-lang.org/regex/regex/struct.Regex.html
|
||||
[`ring::pbkdf2`]: https://docs.rs/ring/*/ring/pbkdf2/index.html
|
||||
[`Rng::gen_range`]: https://doc.rust-lang.org/rand/rand/trait.Rng.html#method.gen_range
|
||||
[`RwLock`]: https://doc.rust-lang.org/std/sync/struct.RwLock.html
|
||||
[`SecureRandom::fill`]: https://docs.rs/ring/*/ring/rand/trait.SecureRandom.html#tymethod.fill
|
||||
[`seek`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.seek
|
||||
[`Stdio::piped`]: https://doc.rust-lang.org/std/process/struct.Stdio.html
|
||||
[rand-distributions]: https://doc.rust-lang.org/rand/rand/distributions/index.html
|
||||
|
|
|
@ -38,6 +38,7 @@ community. It needs and welcomes help. For details see
|
|||
| [Extract phone numbers from text][ex-phone] | [![regex-badge]][regex] | [![cat-text-processing-badge]][cat-text-processing] |
|
||||
| [Calculate the SHA-256 digest of a file][ex-sha-digest] | [![ring-badge]][ring] [![data-encoding-badge]][data-encoding] | [![cat-cryptography-badge]][cat-cryptography] |
|
||||
| [Sign and verify a message with an HMAC digest][ex-hmac] | [![ring-badge]][ring] | [![cat-cryptography-badge]][cat-cryptography] |
|
||||
| [Salt and hash a password with PBKDF2][ex-pbkdf2] | [![ring-badge]][ring] [![data-encoding-badge]][data-encoding] | [![cat-cryptography-badge]][cat-cryptography] |
|
||||
| [Define and operate on a type represented as a bitfield][ex-bitflags] | [![bitflags-badge]][bitflags] | [![cat-no-std-badge]][cat-no-std] |
|
||||
| [Access a file randomly using a memory map][ex-random-file-access] | [![memmap-badge]][memmap] | [![cat-filesystem-badge]][cat-filesystem] |
|
||||
| [Check number of logical cpu cores][ex-check-cpu-cores] | [![num_cpus-badge]][num_cpus] | [![cat-hardware-support-badge]][cat-hardware-support] |
|
||||
|
@ -182,6 +183,7 @@ community. It needs and welcomes help. For details see
|
|||
[ex-paginated-api]: net.html#ex-paginated-api
|
||||
[ex-parse-subprocess-output]: basics.html#ex-parse-subprocess-output
|
||||
[ex-parse-subprocess-input]: basics.html#ex-parse-subprocess-input
|
||||
[ex-pbkdf2]: basics.html#ex-pbkdf2
|
||||
[ex-run-piped-external-commands]: basics.html#ex-run-piped-external-commands
|
||||
[ex-verify-extract-email]: basics.html#ex-verify-extract-email
|
||||
[ex-percent-encode]: encoding.html#ex-percent-encode
|
||||
|
|
Loading…
Reference in a new issue