diff --git a/src/cookbook/cryptography/encryption.md b/src/cookbook/cryptography/encryption.md index c3e253eb..a728da46 100644 --- a/src/cookbook/cryptography/encryption.md +++ b/src/cookbook/cryptography/encryption.md @@ -1 +1,57 @@ # 加密 + +### 使用 PBKDF2 对密码进行哈希和加盐( salt ) +[ring::pbkdf2]() 可以对一个加盐密码进行哈希。 + +```rust,editable + +use data_encoding::HEXUPPER; +use ring::error::Unspecified; +use ring::rand::SecureRandom; +use ring::{digest, pbkdf2, rand}; +use std::num::NonZeroU32; + +fn main() -> Result<(), Unspecified> { + const CREDENTIAL_LEN: usize = digest::SHA512_OUTPUT_LEN; + let n_iter = NonZeroU32::new(100_000).unwrap(); + let rng = rand::SystemRandom::new(); + + let mut salt = [0u8; CREDENTIAL_LEN]; + // 生成 salt: 将安全生成的随机数填入到字节数组中 + rng.fill(&mut salt)?; + + let password = "Guess Me If You Can!"; + let mut pbkdf2_hash = [0u8; CREDENTIAL_LEN]; + pbkdf2::derive( + pbkdf2::PBKDF2_HMAC_SHA512, + n_iter, + &salt, + password.as_bytes(), + &mut pbkdf2_hash, + ); + println!("Salt: {}", HEXUPPER.encode(&salt)); + println!("PBKDF2 hash: {}", HEXUPPER.encode(&pbkdf2_hash)); + + // `verify` 检查哈希是否正确 + let should_`succeed = pbkdf2::verify( + pbkdf2::PBKDF2_HMAC_SHA512, + n_iter, + &salt, + password.as_bytes(), + &pbkdf2_hash, + ); + let wrong_password = "Definitely not the correct password"; + let should_fail = pbkdf2::verify( + pbkdf2::PBKDF2_HMAC_SHA512, + n_iter, + &salt, + wrong_password.as_bytes(), + &pbkdf2_hash, + ); + + assert!(should_succeed.is_ok()); + assert!(!should_fail.is_ok()); + + Ok(()) +} +``` \ No newline at end of file