Encryption at Rest vs In Transit — Two Different Threats
In transit (TLS) protects against interception on the wire. At rest (AES-256) protects against physical disk access or storage breach.
When to use
- Always for PII, financial, health data
- TLS for all service communication, including internal services (zero trust)
Tradeoffs
- TLS 1.3 overhead is negligible; older TLS versions have cipher vulnerabilities
- Encryption at rest doesn't protect a compromised application with DB access
| Threat | At Rest | In Transit |
|---|---|---|
| Network eavesdropping | No | Yes |
| Disk theft / storage breach | Yes | No |
| Compromised app with DB access | No | No |
| Man-in-the-middle | No | Yes |
- Go
- Python
// TLS server — enforce minimum TLS 1.2, prefer 1.3
tlsCfg := &tls.Config{
MinVersion: tls.VersionTLS12,
PreferServerCipherSuites: true,
}
srv := &http.Server{Addr: ":443", TLSConfig: tlsCfg}
srv.ListenAndServeTLS("cert.pem", "key.pem")
// AES-256-GCM encrypt
func encrypt(key, plaintext []byte) ([]byte, error) {
block, _ := aes.NewCipher(key) // key must be 32 bytes
gcm, _ := cipher.NewGCM(block)
nonce := make([]byte, gcm.NonceSize())
io.ReadFull(rand.Reader, nonce)
return gcm.Seal(nonce, nonce, plaintext, nil), nil
}
func decrypt(key, ciphertext []byte) ([]byte, error) {
block, _ := aes.NewCipher(key)
gcm, _ := cipher.NewGCM(block)
nonce, data := ciphertext[:gcm.NonceSize()], ciphertext[gcm.NonceSize():]
return gcm.Open(nil, nonce, data, nil)
}
import ssl
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os
# TLS server context — minimum TLS 1.2
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.minimum_version = ssl.TLSVersion.TLSv1_2
ctx.load_cert_chain("cert.pem", "key.pem")
# AES-256-GCM encrypt/decrypt
def encrypt(key: bytes, plaintext: bytes) -> bytes:
aesgcm = AESGCM(key) # key must be 32 bytes
nonce = os.urandom(12)
return nonce + aesgcm.encrypt(nonce, plaintext, None)
def decrypt(key: bytes, data: bytes) -> bytes:
aesgcm = AESGCM(key)
return aesgcm.decrypt(data[:12], data[12:], None)
Gotcha: Encrypting data at rest protects you from physical disk theft — not from an attacker with DB credentials. Access control is your first defense; encryption is your last.