Go HMAC Code Example (Online Runner)

Go HMAC examples with SHA-1/SHA-2/SHA-3/RIPEMD-160/MD5 and encoding controls to match the HMAC tool.

Online calculator: use the site HMAC text tool.

Note: This snippet requires locally installed dependencies and will not run in the online runner. Run it locally with: go mod init hmac-demo && go get golang.org/x/crypto/sha3 && go run hmac_basic.go

Calculation method

Decode message and key (UTF-8, hex, or base64), compute HMAC with the selected hash, then encode output as hex or base64.

Implementation notes

  • Package: standard crypto/* plus golang.org/x/crypto/sha3 and golang.org/x/crypto/ripemd160.
  • Implementation: the hash factory map mirrors the tool algorithm list.
  • Notes: HMAC requires a non-empty key; keep key encoding consistent across systems.

Text HMAC example

go
package main

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

func hmacSHA256(message, key string) string {
	mac := hmac.New(sha256.New, []byte(key))
	mac.Write([]byte(message))
	return hex.EncodeToString(mac.Sum(nil))
}

func main() {
	fmt.Println(hmacSHA256("hello", "secret"))
}

File HMAC example

go
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io"
	"os"
)

func hmacFile(path string, key []byte) (string, error) {
	file, err := os.Open(path)
	if err != nil {
		return "", err
	}
	defer file.Close()

	mac := hmac.New(sha256.New, key)
	if _, err := io.Copy(mac, file); err != nil {
		return "", err
	}
	return hex.EncodeToString(mac.Sum(nil)), nil
}

func main() {
	file, err := os.CreateTemp("", "hmac-example-*.bin")
	if err != nil {
		panic(err)
	}
	defer os.Remove(file.Name())
	file.WriteString("example payload\n")
	file.Close()

	value, err := hmacFile(file.Name(), []byte("secret"))
	if err != nil {
		panic(err)
	}
	fmt.Println(value)
}

Complete script (implementation + tests)

go
package main

import (
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/base64"
	"encoding/hex"
	"errors"
	"fmt"
	"hash"

	"golang.org/x/crypto/ripemd160"
	"golang.org/x/crypto/sha3"
)

type Algorithm string

type InputEncoding string

type OutputEncoding string

const (
	AlgSHA1     Algorithm = "sha1"
	AlgSHA224   Algorithm = "sha224"
	AlgSHA256   Algorithm = "sha256"
	AlgSHA384   Algorithm = "sha384"
	AlgSHA512   Algorithm = "sha512"
	AlgSHA3_256 Algorithm = "sha3-256"
	AlgSHA3_512 Algorithm = "sha3-512"
	AlgRIPEMD   Algorithm = "ripemd160"
	AlgMD5      Algorithm = "md5"
)

const (
	EncUTF8   InputEncoding = "utf8"
	EncHex    InputEncoding = "hex"
	EncBase64 InputEncoding = "base64"
)

const (
	OutHex    OutputEncoding = "hex"
	OutBase64 OutputEncoding = "base64"
)

func hashFactory(alg Algorithm) (func() hash.Hash, error) {
	switch alg {
	case AlgSHA1:
		return sha1.New, nil
	case AlgSHA224:
		return sha256.New224, nil
	case AlgSHA256:
		return sha256.New, nil
	case AlgSHA384:
		return sha512.New384, nil
	case AlgSHA512:
		return sha512.New, nil
	case AlgSHA3_256:
		return sha3.New256, nil
	case AlgSHA3_512:
		return sha3.New512, nil
	case AlgRIPEMD:
		return ripemd160.New, nil
	case AlgMD5:
		return md5.New, nil
	default:
		return nil, errors.New("unsupported algorithm")
	}
}

func decodeInput(value string, enc InputEncoding) ([]byte, error) {
	switch enc {
	case EncHex:
		return hex.DecodeString(value)
	case EncBase64:
		return base64.StdEncoding.DecodeString(value)
	case EncUTF8:
		fallthrough
	default:
		return []byte(value), nil
	}
}

func encodeOutput(data []byte, enc OutputEncoding) string {
	if enc == OutBase64 {
		return base64.StdEncoding.EncodeToString(data)
	}
	return hex.EncodeToString(data)
}

func hmacDigest(message, key string, alg Algorithm, msgEnc InputEncoding, keyEnc InputEncoding, outEnc OutputEncoding) (string, error) {
	hashFn, err := hashFactory(alg)
	if err != nil {
		return "", err
	}
	msgBytes, err := decodeInput(message, msgEnc)
	if err != nil {
		return "", err
	}
	keyBytes, err := decodeInput(key, keyEnc)
	if err != nil {
		return "", err
	}
	if len(keyBytes) == 0 {
		return "", errors.New("HMAC key must not be empty")
	}

	mac := hmac.New(hashFn, keyBytes)
	mac.Write(msgBytes)
	return encodeOutput(mac.Sum(nil), outEnc), nil
}

func main() {
	mac, err := hmacDigest("hello", "secret", AlgSHA256, EncUTF8, EncUTF8, OutHex)
	if err != nil {
		panic(err)
	}
	fmt.Println("HMAC-SHA256=", mac)

	mac3, err := hmacDigest("hello", "736563726574", AlgSHA3_256, EncUTF8, EncHex, OutBase64)
	if err != nil {
		panic(err)
	}
	fmt.Println("HMAC-SHA3-256=", mac3)
}