argonautica
argonautica copied to clipboard
How to reuse a `Hasher` and `Verifier`?
I'd like to keep a hasher around and use it to hash password. Something like:
pub struct AuthService {
secret_key: String,
hasher: Hasher<'static>,
verifier: Verifier<'static>,
}
impl AuthService {
pub fn new(secret_key: String, hasher_iterations: u32, hasher_memory: u32) -> Self {
let mut hasher = Hasher::default();
hasher
.configure_memory_size(hasher_memory)
.configure_iterations(hasher_iterations);
Self {
secret_key,
hasher,
verifier: Verifier::default(),
}
}
pub fn hash_password(&self, password: &str) -> String {
self.hasher
.with_password(password)
.with_secret_key(&self.secret_key)
.hash()
.unwrap()
}
pub fn verify_password(&self, password: &str, hash: &str) -> bool {
self.verifier
.with_hash(hash)
.with_password(password)
.with_secret_key(&self.secret_key)
.verify()
.unwrap()
}
}
But the problem is that the lifetime parameter of both Hasher
and Verifier
are tied to the lifetime of the password itself. With the code above, the compiler expects my passwords to have the 'static
lifetime:
--> src/main.rs:25:14
|
23 | pub fn hash_password(&self, password: &str) -> String {
| ---- help: add explicit lifetime `'static` to the type of `password`: `&'static str`
24 | self.hasher
25 | .with_password(password)
| ^^^^^^^^^^^^^ lifetime `'static` required
error[E0621]: explicit lifetime required in the type of `password`
--> src/main.rs:33:14
|
31 | pub fn verify_password(&self, password: &str, hash: &str) -> bool {
| ---- help: add explicit lifetime `'static` to the type of `password`: `&'static str`
32 | self.verifier
33 | .with_hash(hash)
| ^^^^^^^^^ lifetime `'static` required
My questions are:
- does it make sense to reuse the
Hasher
andVerifier
instead of always creating new ones? (edit: I guess this question is the same as https://github.com/bcmyers/argonautica/issues/22) - if it does make sense, how can this be achieved?
Another solution is to turn the password and secret key into actual String
s, but again that seems rather inefficient:
pub struct AuthService {
secret_key: String,
hasher: Hasher<'static>,
verifier: Verifier<'static>,
}
impl AuthService {
pub fn new(secret_key: String, hasher_iterations: u32, hasher_memory: u32) -> Self {
let mut hasher = Hasher::default();
hasher
.configure_memory_size(hasher_memory)
.configure_iterations(hasher_iterations);
Self {
secret_key,
hasher,
verifier: Verifier::default(),
}
}
pub fn hash_password(&mut self, password: &str) -> String {
self.hasher
.with_password(password.to_string())
.with_secret_key(self.secret_key.clone())
.hash()
.unwrap()
}
pub fn verify_password(&mut self, password: &str, hash: &str) -> bool {
self.verifier
.with_hash(hash)
.with_password(password.to_string())
.with_secret_key(self.secret_key.clone())
.verify()
.unwrap()
}
}