我目前正在为标准文件创建一个客户端,其中涉及使用PBKDF2的安全性。我正在使用 rust-crypto,尽管我已经尝试过环和 rust-openssl。
首先,通过 /auth/param
终结点从服务器检索盐、成本和版本号。我用 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 字符串以正确加密使用?是否有另一个功能库?还是这是一个失败的事业?
根据标准文件文档,密钥应进行十六进制编码(请参阅代码示例中的注释(。所以这样的事情应该有效:
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]
,因为看起来盐也应该进行十六进制编码。