Encrypt
block, _ := aes.NewCipher(key)
gcm, _ := cipher.NewGCM(block)
nonce := make([]byte, gcm.NonceSize())
rand.Read(nonce)
ciphertext := gcm.Seal(nonce, nonce, plaintext, additionalData)
// ciphertext prepends the nonce for storage
crypto/cipherBlock-cipher modes: GCM, CBC, CTR, CFB, OFB. GCM is what you almost always want.
GCM encrypts AND authenticates. One call to Seal, one call to Open. Never reuse (key, nonce) — generate a fresh nonce per message.
block, _ := aes.NewCipher(key)
gcm, _ := cipher.NewGCM(block)
nonce := make([]byte, gcm.NonceSize())
rand.Read(nonce)
ciphertext := gcm.Seal(nonce, nonce, plaintext, additionalData)
// ciphertext prepends the nonce for storage
nonceSize := gcm.NonceSize()
nonce, ct := ciphertext[:nonceSize], ciphertext[nonceSize:]
plaintext, err := gcm.Open(nil, nonce, ct, additionalData)
if err != nil { return errors.New("invalid ciphertext") }
Only when interoperating with a legacy system that requires them. They don't authenticate — you must add HMAC yourself and get the order right (encrypt-then-MAC). Prefer GCM.