I am currently working on creating a client for Standard File, which involves using PBKDF2 for security. I'm using rust-crypto, although I have experimented with ring and rust-openssl.
First, you retrieve a salt, cost and version number from the server through the /auth/param
endpoint. I have these serialized into a struct with Serde.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct PWHash {
pub pw_salt: String,
pub pw_cost: u32,
pub version: String,
}
Previous clients I have looked at implemented using Python, where the PBKDF2 functions all seem to accept strings. However, for PBKDF2 with Rust, they all accept &[u8]
as the parameter.
I use .as_bytes()
when calling the function, and then str::from_utf8
to output the derived key. However, when doing so, it fails with Err(Utf8Error { valid_up_to: 0, error_len: Some(1) })
.
Here is a code snippet:
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));
}
Even String::from_utf8_lossy
returns a result of unreadable characters.
How do I properly format a Rust string for proper cryptographic use? Is there another library that is functional? Or is this a lost cause?
According to the Standard File documentation, the key should be hex-encoded (see the comments in the code sample). So something like this should work:
Note that I've also used
from_hex
to convert the salt from a string to a&[u8]
since it looks like the salt should also be hex-encoded.