Cryptography 使用PBKDF2密钥派生正确创建具有rust crypto的用户可读的salt

Cryptography 使用PBKDF2密钥派生正确创建具有rust crypto的用户可读的salt,cryptography,rust,Cryptography,Rust,我目前正在为创建一个客户端,其中涉及使用PBKDF2进行安全性保护。我使用的是rust crypto,尽管我已经尝试过使用ring和rust openssl 首先,通过/auth/param端点从服务器检索salt、成本和版本号。我已经用Serde将它们序列化为一个结构 #[derive(Serialize, Deserialize, Clone, Debug)] pub struct PWHash { pub pw_salt: String, pub pw_cost: u32,

我目前正在为创建一个客户端,其中涉及使用PBKDF2进行安全性保护。我使用的是rust crypto,尽管我已经尝试过使用ring和rust openssl

首先,通过
/auth/param
端点从服务器检索salt、成本和版本号。我已经用Serde将它们序列化为一个结构

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct PWHash {
    pub pw_salt: String,
    pub pw_cost: u32,
    pub version: String,
}
我之前看过的客户端是使用Python实现的,其中PBKDF2函数似乎都接受字符串。但是,对于生锈的PBKDF2,它们都接受
和[u8]
作为参数

调用函数时使用
.as_bytes()
,然后使用
str::from_utf8
输出派生键。但是,执行此操作时,它会失败,出现
Err(Utf8Error{valid\u up\u to:0,error\u 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字符串以正确使用加密?还有其他功能性的图书馆吗?或者这是一个丢失的原因?

根据标准文件,密钥应该是十六进制编码的(参见代码示例中的注释)。因此,类似这样的方法应该有效:

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看起来也应该是十六进制编码的。

为什么您希望密钥是正确的UTF-8?@mcarton我猜这是“用户可读”部分的一部分。胡乱猜测:其他语言会自动对原始数据进行十六进制或base64编码。@Shepmaster:您的评论正好说明了为什么自动对原始数据进行编码是个坏主意:有两种(常用)方法表示密钥。
rustc_serialize
被弃用,通常支持
serde
,但这一次,我认为
serde
没有这个功能。有一个板条箱看起来很合适,虽然我从来没有用过。