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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用PBKDF2密钥派生来正确创建用户可读的salt with dry-crypto相关的知识,希望对你有一定的参考价值。

我目前正在为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字符串以进行正确的加密使用?还有另一个功能正常的库吗?或者这是一个失败的原因?

答案

根据标准文件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将盐从字符串转换为&[u8],因为看起来盐也应该是十六进制编码的。

以上是关于使用PBKDF2密钥派生来正确创建用户可读的salt with dry-crypto的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP 可读的 javascript 中创建 PEM 密钥对

Nodejs crypto.pbkdf2 结果与 CryptoJS.PBKDF2 不同

Android中的PBKDF2函数

Java - 使用 HMACSHA256 作为 PRF 的 PBKDF2

Crypto++ pbkdf2 输出不同于 Rfc2898DeriveBytes (C#) 和 crypto.pbkdf2 (JavaScript)

充气城堡 C# 中的 PBKDF2