1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use generic_array::{ArrayLength, GenericArray};
use hmac::crypto_mac::Mac;
use hmac::digest::{BlockInput, Digest, FixedOutput, Input, Reset};
pub trait DeriveKey {
fn derive_key<Digest>(secret_key: &str, salt: &str) -> GenericArray<u8, Digest::OutputSize>
where
Digest: Input + BlockInput + FixedOutput + Reset + Default + Clone,
Digest::BlockSize: ArrayLength<u8> + Clone,
Digest::OutputSize: ArrayLength<u8>;
}
pub struct Concat;
pub struct DjangoConcat;
pub struct Hmac;
macro_rules! derive_key_impl {
($type:ty, ($secret_key:ident, $salt:ident) => $impl: block) => {
impl DeriveKey for $type {
fn derive_key<Digest>(
$secret_key: &str,
$salt: &str,
) -> GenericArray<u8, Digest::OutputSize>
where
Digest: Input + BlockInput + FixedOutput + Reset + Default + Clone,
Digest::BlockSize: ArrayLength<u8> + Clone,
Digest::OutputSize: ArrayLength<u8>,
{
$impl
}
}
};
}
derive_key_impl!(Concat, (secret_key, salt) => {
let mut digest = Digest::new();
digest.input(salt.as_bytes());
digest.input(secret_key.as_bytes());
digest.result()
});
derive_key_impl!(DjangoConcat, (secret_key, salt) => {
let mut digest = Digest::new();
digest.input(salt.as_bytes());
digest.input("signer".as_bytes());
digest.input(secret_key.as_bytes());
digest.result()
});
derive_key_impl!(Hmac, (secret_key, salt) => {
let mut mac: hmac::Hmac<Digest> =
hmac::Hmac::new_varkey(secret_key.as_bytes()).unwrap();
mac.input(salt.as_bytes());
mac.result().code()
});