07/11/2020 - GO
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.
Alternative to hex
encoder, you can use base64.URLEncoding/base64.RawStdEncoding
functions for shorter results.
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")
}
}
// SUCCESS
HASH: be52bab9c7fd1ff2cbb9636da28acfe1f5cc25f12ab49d8f69163dcd9f455907
OK
// FAILURE
// If you give a different message or hash as opposed to original one
HASH: be52bab9c7fd1ff2cbb9636da28acfe1f5cc25f12ab49d8f69163dcd9f455907
Tampered