We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Encrypting Data at Rest

HTTPS protects data in transit. It does nothing once the data is stored.

If someone steals a database file, uploaded document, or backup, encryption at rest can prevent them from reading it without the key. If you're storing especially sensitive values in a database, like a user's API key or shipping details, consider field-level encryption.

Authenticated Encryption

AES-GCM is a type of authenticated, symmetric encryption. It provides:

  • Confidentiality: The plaintext becomes unreadable ciphertext.
  • Integrity: An authentication tag detects changes to the encrypted value.

Click to play video

The Encrypted Payload

When you encrypt a value with AES-GCM, it produces three pieces that need to stay together:

  • The ciphertext, which replaces the plaintext
  • A 12-byte nonce, also called an initialization vector (IV)
  • A 16-byte authentication tag, which detects tampering

The nonce and authentication tag aren't secrets, so you can just store them alongside the ciphertext. The 32-byte AES-256 key is the secret.

Every encryption that uses the same key needs a unique nonce. Reusing a GCM nonce can destroy both confidentiality and integrity, so generate a fresh one with crypto/rand each time you encrypt:

block, err := aes.NewCipher(key[:])
if err != nil {
    return err
}
aead, err := cipher.NewGCM(block)
if err != nil {
    return err
}
nonce := make([]byte, aead.NonceSize())
if _, err := rand.Read(nonce); err != nil {
    return err
}
sealed := aead.Seal(nil, nonce, plaintext, nil)

Go's GCM implementation appends the authentication tag to the ciphertext returned by Seal. Decryption reconstructs that sealed value and calls Open, which returns an error if the key, nonce, ciphertext, or tag is wrong.

The helper should accept byte slices instead of strings so it can later protect JSON, database fields, and binary files without changing cryptographic formats.

Assignment

Bearly Secure needs one safe primitive for sensitive stored data. Add reusable AES-256-GCM encryption and decryption.

Run and submit the CLI tests from the project root.