TazPod: Crypto Detail
Level 3 (Detail) — AES-256-GCM encryption engine with PBKDF2 key derivation.
Concept
The vault is encrypted at the application layer using AES-256-GCM authenticated encryption. The passphrase is derived through PBKDF2 with a random salt. The output format is [salt(32)] + [nonce(12)] + [ciphertext+tag].
Encryption
File: internal/crypto/crypto.go — Encrypt() (lines 15-52)
func Encrypt(data []byte, passphrase string) ([]byte, error)
- Generate 32 random bytes (salt) via
crypto/rand - Derive 32-byte key:
pbkdf2.Key(passphrase, salt, 100000, 32, sha256.New) - Create AES cipher:
aes.NewCipher(key) - Create GCM:
cipher.NewGCM(block)— uses 12-byte nonce - Generate 12 random bytes (nonce) via
crypto/rand - Seal:
aesGCM.Seal(nil, nonce, data, nil) - Output:
salt || nonce || ciphertext
Decryption
File: internal/crypto/crypto.go — Decrypt() (lines 56-83)
func Decrypt(data []byte, passphrase string) ([]byte, error)
- Validate minimum length:
SaltSize + NonceSize(44 bytes) - Extract salt:
data[:32] - Extract nonce:
data[32:44] - Extract ciphertext:
data[44:] - Re-derive key:
pbkdf2.Key(passphrase, salt, 100000, 32, sha256.New) - Create AES cipher + GCM
- Open:
aesGCM.Open(nil, nonce, ciphertext, nil) - On failure: returns “incorrect password or corrupted file”
Constants
| Constant | Value | Purpose |
|---|---|---|
SaltSize | 32 bytes | Random salt for PBKDF2 |
NonceSize | 12 bytes | Standard GCM nonce |
KeySize | 32 bytes | AES-256 key |
Iterations | 100000 | PBKDF2 iteration count |
Output Format
[Salt: 32 bytes] [Nonce: 12 bytes] [Ciphertext + GCM Tag: variable]
Total overhead: 44 bytes beyond the plaintext size.
Dependencies
golang.org/x/crypto/pbkdf2— key derivationcrypto/aes— AES-256 block ciphercrypto/cipher— GCM modecrypto/rand— cryptographically secure random
Security Properties
- Confidentiality: AES-256-GCM provides authenticated encryption
- Integrity: GCM authentication tag prevents tampering
- Key stretching: PBKDF2 with 100k iterations slows brute-force attacks
- No hardcoded keys: Key is always derived from user passphrase + random salt
- No plaintext on disk: Vault file is always encrypted at rest
See Also
- Parent hub: tazpod
- Sibling details: Vault Lifecycle Detail
- Topic: Vault Security