使用PBKDF2密钥派生来正确创建用户可读的salt with dry-crypto

时间:2018-03-04 22:53:24

标签: cryptography rust

我目前正在为Standard File创建客户端,其中涉及使用PBKDF2来提高安全性。我使用 rust-crypto ,虽然我已尝试使用ring和rust-openssl。

首先,您通过/auth/param端点从服务器检索salt,cost和版本号。我将这些序列化为带有Serde的结构。

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct PWHash {
    pub pw_salt: String,
    pub pw_cost: u32,
    pub version: String,
}

以前的客户端我已经看过使用Python实现,其中PBKDF2函数似乎都接受字符串。但是,对于带有Rust的PBKDF2,它们都接受&[u8]作为参数。

我在调用函数时使用.as_bytes(),然后str::from_utf8输出派生密钥。但是,在执行此操作时,它会失败并显示Err(Utf8Error { valid_up_to: 0, error_len: Some(1) })

以下是代码段:

pub fn hashcompute(&self, password: String) {
    let mut dk = [0u8; 768]; // derived key
    let mut mac = Hmac::new(Sha512::new(), password.as_bytes());
    pbkdf2::pbkdf2(&mut mac, self.pw_salt.as_bytes(), self.pw_cost, &mut dk);

    println!("{:?}", str::from_utf8(&dk));
}

即使String::from_utf8_lossy也会返回不可读字符的结果。

如何正确格式化Rust字符串以进行正确的加密?还有另一个功能正常的库吗?或者这是一个失败的原因?

1 个答案:

答案 0 :(得分:3)

根据标准文件documentation,密钥应该是十六进制编码的(请参阅代码示例中的注释)。所以这样的事情应该有效:

extern crate rustc_serialize as serialize;
use serialize::hex::{FromHex, ToHex};

pub fn hashcompute(&self, password: String) {
    let mut dk = [0u8; 768]; // derived key
    let mut mac = Hmac::new(Sha512::new(), password.as_bytes());
    pbkdf2::pbkdf2(&mut mac, self.pw_salt.from_hex().unwrap(), self.pw_cost, &mut dk);

    println!("{}", dk.to_hex());
}

请注意,我还使用from_hex将字符串中的salt转换为&[u8],因为看起来salt也应该是十六进制编码的。