In this example we are going to sign a message with our secret key to create a HMAC (Keyed-Hash Message Authentication Code) hash and give it to client. Client then verifies the message integrity by recalculating its signature/hash with the same secret to see if it really is coming from you. The secret is shared between both client and server applications. If you give a different message or hash as opposed to original ones, the communication will be treated as tampered.


Example


package message

import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
)

func Sign(msg, key []byte) string {
mac := hmac.New(sha256.New, key)
mac.Write(msg)

return hex.EncodeToString(mac.Sum(nil))
}

func Verify(msg, key []byte, hash string) (bool, error) {
sig, err := hex.DecodeString(hash)
if err != nil {
return false, err
}

mac := hmac.New(sha256.New, key)
mac.Write(msg)

return hmac.Equal(sig, mac.Sum(nil)), nil
}

package main

import (
"fmt"
"message"
)

func main() {
msg := []byte("hello")
key := []byte("some-secret-key")

hash := message.Sign(msg, key)
fmt.Println("HASH:", hash)

if ok, err := message.Verify(msg, key, hash); !ok {
fmt.Println("Tampered")
if err != nil {
fmt.Println("Error:", err)
}
} else {
fmt.Println("OK")
}
}

Test


// SUCCESS

HASH: be52bab9c7fd1ff2cbb9636da28acfe1f5cc25f12ab49d8f69163dcd9f455907
OK

// FAILURE
// If you give a different message or hash as opposed to original one
HASH: be52bab9c7fd1ff2cbb9636da28acfe1f5cc25f12ab49d8f69163dcd9f455907
Tampered