rustcryptographyhmachmacsha1

HMAC-SHA1 in Rust


I'm trying to apply HMAC-SHA1 in order to check some content but I'm unable to make it work.

These are the tests I have:

#[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"));
    }
}

I've used this website in order to get the COMPUTED_HMAC by using one string (BODY_CONTENT) and a secret key (KEY).

As you can see, I'm trying to leverage both rust-crypto and hmac-sha1 crates and I obtain the same result with both of them.

The thing is that this result doesn't match with what I get in the website (97049623b0e5d20bf6beb5313d80600e3d6abe56) and the tests fail. You may think that the website is wrong but that's not the case as I'm using it to validate some other hashes generated by Github (I'm working in a Github App) and it works.

Then, obviously, I'm missing some step here but I'm unable to figure it out and I would really appreciate your help.


Solution

  • The correct hash is returned, it's just not in the representation you expected. The hash is returned as raw bytes, not as bytes converted to ASCII hexadecimal digits.

    If we print the hash code array as hex, like this:

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

    then we can see that it matches your string:

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

    whereas the string "97049623b0e5d20bf6beb5313d80600e3d6abe56" looks like this:

    [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]
    

    Using itertools, we can convert the former to the latter like this:

    assert_eq!(
        COMPUTED_HMAC,
        code.iter().format_with("", |byte, f| f(&format_args!("{:02x}", byte))).to_string());