HMAC (hash-based message authentication code) supports the usage of a key to hash data. This key is kept secret between Bob and Alice, and can be used to authentication both the data and that the sender still knows the secret. Overall HMAC can be used with a range of different hashing methods, such as MD5, SHA-1, SHA-256 (SHA-2) and SHA-3.
HMAC (Key Hash Message Authentication Code) in Golang |
Method
HMAC is a message authentication code (MAC) that can be used to verify the integrity and authentication of a message. It involves hashing the message with a secret key and thus differs from standard hashing, which is purely a one-way function. As with any MAC, it can be used with a standard hash function, such as MD5 or SHA-1, which results in methods such as HMAC-MD5 or HMAC-SHA-1. Also, as with any hashing function, the strength depends on the quality of the hashing function, and the resulting number of hash code bits. Along with this, the number of bits in the secret key is a factor in the strength of the hash. The figure below outlines the operation, where the message to be sent is converted with a secret key, and the hashing function, to an HMAC code. This is then sent with the message. On receipt, the receiver recalculates the HMAC code from the same secret key, and the message, and checks it against the received version. If they match, it validates both the sender and the message.
Coding
The outline code is:
package main import ( "crypto/hmac" "crypto/rand" "crypto/sha256" "crypto/sha512" "encoding/hex" "fmt" "io" "os" ) func getSalt(n int) []byte { nonce := make([]byte, n) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { panic(err.Error()) } return (nonce) } func main() { key:="000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" m := "The quick brown fox jumps over the lazy dog" argCount := len(os.Args[1:]) if argCount > 0 { m = os.Args[1] } if argCount > 1 { key = os.Args[2] } var secretKey, _ = hex.DecodeString(key) message := []byte(m) // salt := getSalt(16) fmt.Printf("Message: %s\n", m) fmt.Printf("Key: %x\n", secretKey) // fmt.Printf("\nSalt: %x\n", salt) hash := hmac.New(sha256.New, []byte(secretKey)) hash.Write(message) // hash.Write(salt) fmt.Printf("\nHMAC-Sha256: %x", hash.Sum(nil)) hash = hmac.New(sha512.New, []byte(secretKey)) hash.Write(message) // hash.Write(salt) fmt.Printf("\n\nHMAC-sha512: %x", hash.Sum(nil)) }
A sample run for 40-bit primes:
Message: The quick brown fox jumps over the lazy dog Key: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f HMAC-Sha256: f87ad256151fc7b4c5dffa4adb3ebe911a8eeb8a8ebdee3c2a4a8e5f5ec02c32 HMAC-sha512: 0623d51f882717efa360aa2217d0b554b57ea018eb518178b23045941a6ae24450af5c980f6ebca94ca5314a8590991b4eab6daa3f0c109345433f44ee234d00