HMAC-SHA1 в Rust

Я пытаюсь применить HMAC-SHA1 для проверки некоторого содержимого, но не могу заставить его работать.

Вот тесты, которые у меня есть:

#[cfg(test)]
mod tests {

    use crypto::hmac::Hmac;
    use crypto::mac::Mac;

    use crypto::sha1::Sha1;
    use std::str::from_utf8;

    const BODY_CONTENT: &'static str = r#"bodystring"#;
    const KEY: &[u8] = b"secret_key";
    const COMPUTED_HMAC: &'static str = "97049623b0e5d20bf6beb5313d80600e3d6abe56";

    #[test]
    fn test_hmac_sha1() {
        let mut mac= Hmac::new(Sha1::new(), KEY);
        mac.input(BODY_CONTENT.as_bytes());
        let result = mac.result();
        let code = result.code();
        assert_eq!(COMPUTED_HMAC.as_bytes(), code);
        assert_eq!(COMPUTED_HMAC, from_utf8(&code).unwrap_or("failed"));
    }

    #[test]
    fn test_hmac_sha1_direct() {
        let hash = hmacsha1::hmac_sha1(KEY, BODY_CONTENT.as_bytes());
        assert_eq!(COMPUTED_HMAC.as_bytes(), hash);
        assert_eq!(COMPUTED_HMAC, from_utf8(&hash).unwrap_or("failed"));
    }
}

Я использовал этот веб-сайт, чтобы получить COMPUTED_HMAC с помощью одной строки (BODY_CONTENT) и секретный ключ (KEY).

Как видите, я пытаюсь использовать как rust-crypto, так и hmac-sha1, и я получаю тот же результат с обоими из них.

Дело в том, что этот результат не совпадает с тем, что я получаю на сайте (97049623b0e5d20bf6beb5313d80600e3d6abe56), и тесты не проходят. Вы можете подумать, что веб-сайт неправильный, но это не так, поскольку я использую его для проверки некоторых других хэшей, сгенерированных Github (я работаю в приложении Github), и он работает.

Тогда, очевидно, мне здесь не хватает какого-то шага, но я не могу его понять и буду очень признателен за вашу помощь.


person robertohuertasm    schedule 10.02.2019    source источник


Ответы (1)


Возвращается правильный хеш, просто он не в том представлении, которое вы ожидали. Хэш возвращается как необработанные байты, а не как байты, преобразованные в шестнадцатеричные цифры ASCII.

Если мы напечатаем массив хэш-кода как шестнадцатеричный, например:

println!("{:02x?}", code);

тогда мы увидим, что он соответствует вашей строке:

[97, 04, 96, 23, b0, e5, d2, 0b, f6, be, b5, 31, 3d, 80, 60, 0e, 3d, 6a, be, 56]
// 97049623b0e5d20bf6beb5313d80600e3d6abe56

тогда как строка "97049623b0e5d20bf6beb5313d80600e3d6abe56" выглядит так:

[39, 37, 30, 34, 39, 36, 32, 33, 62, 30, 65, 35, 64, 32, 30, 62, 66, 36, 62, 65,
 62, 35, 33, 31, 33, 64, 38, 30, 36, 30, 30, 65, 33, 64, 36, 61, 62, 65, 35, 36]

Используя itertools, мы можем преобразовать первое во второе следующим образом:

assert_eq!(
    COMPUTED_HMAC,
    code.iter().format_with("", |byte, f| f(&format_args!("{:02x}", byte))).to_string());
person Francis Gagné    schedule 10.02.2019
comment
Спасибо за Ваш ответ! Я ходил кругами. Наконец, просто преобразование полученного хеша в шестнадцатеричный, как вы предложили, отлично сработало. Я использовал base16 для его кодирования. - person robertohuertasm; 10.02.2019