Computes HMAC-SHA256 (Hash-based Message Authentication Code) for the given key and message. # Arguments `key` - The secret key (can be any length, will be hashed if > 64 bytes) `message` - The message to authenticate # Returns A 32-byte HMAC-SHA256 digest # Example ``` use stringzilla::stringzilla::hmac_sha256; let key = b"secret_key"; let message = b"important message"; let mac = hmac_sha2
(key: &[u8], message: &[u8])
| 623 | /// assert_eq!(mac.len(), 32); |
| 624 | /// ``` |
| 625 | pub fn hmac_sha256(key: &[u8], message: &[u8]) -> [u8; 32] { |
| 626 | // Prepare key: hash if > 64 bytes, zero-pad to 64 bytes |
| 627 | let mut key_pad = [0u8; 64]; |
| 628 | if key.len() > 64 { |
| 629 | let key_hash = Sha256::hash(key); |
| 630 | key_pad[..32].copy_from_slice(&key_hash); |
| 631 | } else { |
| 632 | key_pad[..key.len()].copy_from_slice(key); |
| 633 | } |
| 634 | |
| 635 | // Compute inner hash: SHA256((key ^ 0x36) || message) |
| 636 | let mut inner_hasher = Sha256::new(); |
| 637 | let mut inner_pad = [0u8; 64]; |
| 638 | for i in 0..64 { |
| 639 | inner_pad[i] = key_pad[i] ^ 0x36; |
| 640 | } |
| 641 | inner_hasher.update(&inner_pad); |
| 642 | inner_hasher.update(message); |
| 643 | let inner_hash = inner_hasher.digest(); |
| 644 | |
| 645 | // Compute outer hash: SHA256((key ^ 0x5c) || inner_hash) |
| 646 | let mut outer_hasher = Sha256::new(); |
| 647 | let mut outer_pad = [0u8; 64]; |
| 648 | for i in 0..64 { |
| 649 | outer_pad[i] = key_pad[i] ^ 0x5c; |
| 650 | } |
| 651 | outer_hasher.update(&outer_pad); |
| 652 | outer_hasher.update(&inner_hash); |
| 653 | outer_hasher.digest() |
| 654 | } |
| 655 | |
| 656 | /// Standard Hasher trait to interoperate with `std::collections`. |
| 657 | impl core::hash::Hasher for Hasher { |
searching dependent graphs…