Go AES-GCM Code Example (Online Runner)
Go AES-GCM examples with tag length, AAD, and encoding controls matching the AES-GCM tool.
Online calculator: use the site AES-GCM tool.
Calculation method
AES-GCM combines encryption and authentication. The tool concatenates ciphertext + tag; this helper matches that output.
Implementation notes
- Package: built-in
crypto/aesandcrypto/cipher. - Implementation:
Sealreturns ciphertext+tag, which matches the UI output. - Notes: nonces must be unique per key; AAD must match during decryption.
Text encryption example
go
package main
import (
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"fmt"
)
func aesGCMEncryptHex(plaintext string, keyHex string, nonceHex string) (string, error) {
key, err := hex.DecodeString(keyHex)
if err != nil {
return "", err
}
nonce, err := hex.DecodeString(nonceHex)
if err != nil {
return "", err
}
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
aead, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
out := aead.Seal(nil, nonce, []byte(plaintext), nil)
return hex.EncodeToString(out), nil
}
func main() {
keyHex := "00112233445566778899aabbccddeeff"
nonceHex := "0102030405060708090a0b0c"
value, err := aesGCMEncryptHex("hello", keyHex, nonceHex)
if err != nil {
panic(err)
}
fmt.Println(value)
}Complete script (implementation + tests)
go
package main
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
)
type KeyEncoding string
type CipherEncoding string
const (
EncUTF8 KeyEncoding = "utf8"
EncHex KeyEncoding = "hex"
)
const (
CipherHex CipherEncoding = "hex"
CipherBase64 CipherEncoding = "base64"
)
func decodeValue(value string, encoding KeyEncoding) ([]byte, error) {
if encoding == EncHex {
return hex.DecodeString(value)
}
return []byte(value), nil
}
func normalizeKey(key []byte, keySize int) []byte {
if len(key) >= keySize {
return key[:keySize]
}
out := make([]byte, keySize)
copy(out, key)
return out
}
func encodeCiphertext(data []byte, encoding CipherEncoding) string {
if encoding == CipherHex {
return hex.EncodeToString(data)
}
return base64.StdEncoding.EncodeToString(data)
}
func decodeCiphertext(value string, encoding CipherEncoding) ([]byte, error) {
if encoding == CipherHex {
return hex.DecodeString(value)
}
return base64.StdEncoding.DecodeString(value)
}
func aesGCMEncrypt(plaintext, key, nonce string, keyEnc, nonceEnc KeyEncoding, aad string, aadEnc KeyEncoding, tagLen, keySize int, outEnc CipherEncoding) (string, error) {
keyBytes, err := decodeValue(key, keyEnc)
if err != nil {
return "", err
}
nonceBytes, err := decodeValue(nonce, nonceEnc)
if err != nil {
return "", err
}
keyBytes = normalizeKey(keyBytes, keySize)
block, err := aes.NewCipher(keyBytes)
if err != nil {
return "", err
}
aead, err := cipher.NewGCMWithTagSize(block, tagLen)
if err != nil {
return "", err
}
var aadBytes []byte
if aad != "" {
aadBytes, err = decodeValue(aad, aadEnc)
if err != nil {
return "", err
}
}
ciphertext := aead.Seal(nil, nonceBytes, []byte(plaintext), aadBytes)
return encodeCiphertext(ciphertext, outEnc), nil
}
func aesGCMDecrypt(combined, key, nonce string, keyEnc, nonceEnc KeyEncoding, aad string, aadEnc KeyEncoding, tagLen, keySize int, inEnc CipherEncoding) (string, error) {
keyBytes, err := decodeValue(key, keyEnc)
if err != nil {
return "", err
}
nonceBytes, err := decodeValue(nonce, nonceEnc)
if err != nil {
return "", err
}
keyBytes = normalizeKey(keyBytes, keySize)
block, err := aes.NewCipher(keyBytes)
if err != nil {
return "", err
}
aead, err := cipher.NewGCMWithTagSize(block, tagLen)
if err != nil {
return "", err
}
data, err := decodeCiphertext(combined, inEnc)
if err != nil {
return "", err
}
if len(data) < tagLen {
return "", errors.New("ciphertext must include tag")
}
var aadBytes []byte
if aad != "" {
aadBytes, err = decodeValue(aad, aadEnc)
if err != nil {
return "", err
}
}
plaintext, err := aead.Open(nil, nonceBytes, data, aadBytes)
if err != nil {
return "", err
}
return string(plaintext), nil
}
func main() {
key := "00112233445566778899aabbccddeeff"
nonce := "0102030405060708090a0b0c"
ciphertext, err := aesGCMEncrypt("hello", key, nonce, EncHex, EncHex, "context", EncUTF8, 16, 16, CipherHex)
if err != nil {
panic(err)
}
fmt.Println("cipher=", ciphertext)
plain, err := aesGCMDecrypt(ciphertext, key, nonce, EncHex, EncHex, "context", EncUTF8, 16, 16, CipherHex)
if err != nil {
panic(err)
}
fmt.Println("plain=", plain)
}