Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 509
robertohuertasm Avatar asked Feb 10 '19 18:02

robertohuertasm


People also ask

Is SHA1 secure for HMAC?

Description. The remote SSH server is configured to enable SHA-1 HMAC algorithms. Although NIST has formally deprecated use of SHA-1 for digital signatures, SHA-1 is still considered secure for HMAC as the security of HMAC does not rely on the underlying hash function being resistant to collisions.

Is HMAC deprecated?

HISTORY. All functions except for HMAC() were deprecated in OpenSSL 3.0. HMAC_CTX_init() was replaced with HMAC_CTX_reset() in OpenSSL 1.1. 0.


1 Answers

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());
like image 77
Francis Gagné Avatar answered Oct 07 '22 02:10

Francis Gagné