What it does. Guides implementing AES-256 encryption in GCM mode (FIPS 197) for files and data stores at rest, covering key derivation, IV/nonce management, and authenticated encryption. Use when deploying or configuring encryption for data at rest, establishing controls to meet compliance requirements, or reviewing an implementation during a security assessment. Part of mukul975/Anthropic-Cybersecurity-Skills (817 security skills) (mukul975/Anthropic-Cybersecurity-Skills).
Install
npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill implementing-aes-encryption-for-data-at-rest, or copy the skill folder into ~/.claude/skills/implementing-aes-encryption-for-data-at-rest/.
- Raw file:
curl -sL https://raw.githubusercontent.com/mukul975/Anthropic-Cybersecurity-Skills/HEAD/skills/implementing-aes-encryption-for-data-at-rest/SKILL.md
SKILL.md (verbatim)
name: implementing-aes-encryption-for-data-at-rest
description: Guides implementing AES-256 encryption in GCM mode (FIPS 197) for files and data stores at rest, covering key derivation, IV/nonce management, and authenticated encryption. Use when deploying or configuring encryption for data at rest, establishing controls to meet compliance requirements, or reviewing an implementation during a security assessment.
domain: cybersecurity
subdomain: cryptography
tags:
- cryptography
- encryption
- aes
- data-at-rest
- symmetric-encryption
version: '1.0'
author: mahipal
license: Apache-2.0
nist_csf:
- PR.DS-01
- PR.DS-02
- PR.DS-10
mitre_attack:
- T1600
- T1573
- T1553
- T1486
Implementing AES Encryption for Data at Rest
Overview
AES (Advanced Encryption Standard) is a symmetric block cipher standardized by NIST (FIPS 197) used to protect classified and sensitive data. This skill covers implementing AES-256 encryption in GCM mode for encrypting files and data stores at rest, including proper key derivation, IV/nonce management, and authenticated encryption.
When to Use
- When deploying or configuring implementing aes encryption for data at rest capabilities in your environment
- When establishing security controls aligned to compliance requirements
- When building or improving security architecture for this domain
- When conducting security assessments that require this implementation
Prerequisites
- Familiarity with cryptography concepts and tools
- Access to a test or lab environment for safe execution
- Python 3.8+ with required dependencies installed
- Appropriate authorization for any testing activities
Objectives
- Implement AES-256-GCM encryption and decryption for files
- Derive encryption keys from passwords using PBKDF2 and Argon2
- Manage initialization vectors (IVs) and nonces securely
- Encrypt and decrypt entire directory trees
- Implement authenticated encryption to detect tampering
- Handle large files with streaming encryption
Key Concepts
AES Modes of Operation
| Mode |
Authentication |
Parallelizable |
Use Case |
| GCM |
Yes (AEAD) |
Yes |
Network data, file encryption |
| CBC |
No |
Decrypt only |
Legacy systems, disk encryption |
| CTR |
No |
Yes |
Streaming encryption |
| CCM |
Yes (AEAD) |
No |
IoT, constrained environments |
Key Derivation
Never use raw passwords as encryption keys. Always derive keys using:
- PBKDF2: NIST-approved, widely supported (minimum 600,000 iterations as of 2024)
- Argon2id: Winner of Password Hashing Competition, memory-hard
- scrypt: Memory-hard, good alternative to Argon2
Nonce/IV Management
- GCM requires a 96-bit (12-byte) nonce that must NEVER be reused with the same key
- Generate nonces using
os.urandom() (CSPRNG)
- Store nonce alongside ciphertext (it is not secret)
Workflow
- Install the
cryptography library: pip install cryptography
- Generate or derive an encryption key
- Create a random nonce for each encryption operation
- Encrypt data using AES-256-GCM with the key and nonce
- Store nonce + ciphertext + authentication tag together
- For decryption, extract nonce, verify tag, and decrypt
[salt: 16 bytes][nonce: 12 bytes][ciphertext: variable][tag: 16 bytes]
Security Considerations
- Always use authenticated encryption (GCM, CCM) to prevent tampering
- Never reuse a nonce with the same key (catastrophic in GCM)
- Use at least 256-bit keys for long-term data protection
- Securely wipe keys from memory after use when possible
- Rotate encryption keys periodically per organizational policy
- For disk-level encryption, consider XTS mode (AES-XTS)
Validation Criteria
Other files in this skill
assets/template.md (verbatim)
AES Encryption Implementation Template
Pre-Implementation Checklist
Configuration Parameters
encryption:
algorithm: AES-256-GCM
key_length: 256
nonce_length: 96 # bits
tag_length: 128 # bits
key_derivation:
algorithm: PBKDF2-SHA256
iterations: 600000
salt_length: 128 # bits
file_format:
magic_bytes: "AES256GCM"
version: 1
header: "magic || version || salt || nonce"
body: "ciphertext || tag"
Integration Code Template
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
import os
def encrypt_data(plaintext: bytes, password: str) -> bytes:
"""Encrypt data with AES-256-GCM."""
salt = os.urandom(16)
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=600_000,
)
key = kdf.derive(password.encode())
nonce = os.urandom(12)
aesgcm = AESGCM(key)
ciphertext = aesgcm.encrypt(nonce, plaintext, None)
return salt + nonce + ciphertext
def decrypt_data(data: bytes, password: str) -> bytes:
"""Decrypt AES-256-GCM encrypted data."""
salt = data[:16]
nonce = data[16:28]
ciphertext = data[28:]
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=600_000,
)
key = kdf.derive(password.encode())
aesgcm = AESGCM(key)
return aesgcm.decrypt(nonce, ciphertext, None)
Testing Checklist
Common Pitfalls
| Pitfall |
Impact |
Mitigation |
| Nonce reuse with same key |
Complete loss of confidentiality in GCM |
Always generate random nonce per encryption |
| Low PBKDF2 iterations |
Brute-force password attacks |
Use minimum 600,000 iterations |
| ECB mode usage |
Pattern leakage in ciphertext |
Always use GCM or CBC (never ECB) |
| No authentication |
Undetected ciphertext modification |
Use AEAD modes (GCM, CCM) |
| Hardcoded keys |
Key compromise |
Use KMS, HSM, or environment variables |
| No key rotation |
Extended exposure window |
Implement periodic key rotation policy |
references/api-reference.md (verbatim)
API Reference: Implementing AES Encryption for Data at Rest
cryptography Library - AESGCM
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os
key = AESGCM.generate_key(bit_length=256)
aesgcm = AESGCM(key)
nonce = os.urandom(12) # 96-bit nonce, NEVER reuse
ciphertext = aesgcm.encrypt(nonce, plaintext, associated_data)
plaintext = aesgcm.decrypt(nonce, ciphertext, associated_data)
Key Derivation - PBKDF2
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32, # 256-bit key
salt=os.urandom(16),
iterations=600_000, # NIST 2024 recommendation
)
key = kdf.derive(password.encode())
[salt: 16 bytes][nonce: 12 bytes][ciphertext + tag: variable]
| Field |
Size |
Purpose |
| Salt |
16 bytes |
PBKDF2 salt (random per file) |
| Nonce |
12 bytes |
GCM nonce (random per encryption) |
| Ciphertext |
Variable |
Encrypted data + 16-byte auth tag |
AES Modes Comparison
| Mode |
AEAD |
Nonce Size |
Use Case |
| GCM |
Yes |
12 bytes |
File/network encryption |
| CBC |
No |
16 bytes |
Legacy, disk encryption |
| CTR |
No |
16 bytes |
Streaming |
| XTS |
No |
16 bytes |
Full disk encryption |
Fernet (High-Level API)
from cryptography.fernet import Fernet
key = Fernet.generate_key()
f = Fernet(key)
token = f.encrypt(b"data")
plaintext = f.decrypt(token)
References
references/standards.md (verbatim)
Standards and References - AES Encryption for Data at Rest
Primary Standards
NIST FIPS 197 - Advanced Encryption Standard (AES)
NIST SP 800-38D - Recommendation for Block Cipher Modes: GCM and GMAC
NIST SP 800-132 - Recommendation for Password-Based Key Derivation
NIST SP 800-38A - Recommendation for Block Cipher Modes of Operation
NIST SP 800-57 Part 1 Rev. 5 - Key Management
RFC Standards
RFC 5116 - An Interface and Algorithms for Authenticated Encryption
RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
RFC 9106 - Argon2 Memory-Hard Function
Compliance Frameworks
PCI DSS v4.0 - Requirement 3
- Encrypt stored cardholder data with strong cryptography
- AES-256 meets the strong cryptography requirement
- Key management procedures required
HIPAA Security Rule - 45 CFR 164.312(a)(2)(iv)
- Encryption of ePHI at rest is an addressable implementation specification
- AES-256 is an acceptable encryption method
GDPR Article 32 - Security of Processing
- Encryption is listed as an appropriate technical measure
- AES-256 satisfies encryption requirements for personal data protection
Python Library References
cryptography (pyca/cryptography)
PyCryptodome
references/workflows.md (verbatim)
Workflows - AES Encryption for Data at Rest
Workflow 1: Single File Encryption
[Input File] --> [Read File Bytes]
|
[Derive Key from Password]
(PBKDF2 / Argon2id + random salt)
|
[Generate Random Nonce]
(12 bytes from CSPRNG)
|
[AES-256-GCM Encrypt]
(key + nonce + plaintext --> ciphertext + tag)
|
[Write Encrypted File]
(salt || nonce || ciphertext || tag)
Workflow 2: Single File Decryption
[Encrypted File] --> [Parse Header]
(extract salt, nonce)
|
[Derive Key from Password]
(same PBKDF2 / Argon2id params + extracted salt)
|
[AES-256-GCM Decrypt]
(key + nonce + ciphertext + tag)
|
[Verify Authentication Tag]
(reject if tag invalid)
|
[Write Decrypted File]
Workflow 3: Streaming Encryption for Large Files
[Large Input File]
|
[Read in Chunks] (e.g., 64KB chunks)
|
[For Each Chunk]:
- [Encrypt chunk with AES-256-CTR]
- [Update HMAC with ciphertext chunk]
- [Write encrypted chunk to output]
|
[Finalize HMAC]
[Append HMAC tag to output]
Workflow 4: Directory Tree Encryption
[Source Directory]
|
[Walk Directory Tree]
|
[For Each File]:
- [Derive unique file key from master key + file path]
- [Generate random nonce]
- [AES-256-GCM encrypt file]
- [Write encrypted file preserving directory structure]
|
[Create Manifest File]
(maps original paths to encrypted paths with metadata)
Workflow 5: Key Derivation Pipeline
[User Password]
|
[Generate Random Salt] (16 bytes)
|
[PBKDF2-SHA256]
- iterations: 600,000+
- dkLen: 32 bytes (256 bits)
|
[Derived Key (256-bit)]
|
[Optional: HKDF Expand]
- Derive multiple subkeys from single derived key
- info="encryption" --> encryption key
- info="authentication" --> HMAC key
Workflow 6: Envelope Encryption Pattern
[Master Key] (stored in HSM/KMS)
|
[Generate Random Data Encryption Key (DEK)]
(32 bytes from CSPRNG)
|
[Encrypt DEK with Master Key] --> [Encrypted DEK]
|
[Encrypt Data with DEK] --> [Ciphertext]
|
[Store: Encrypted DEK + Ciphertext]
[Securely Wipe DEK from Memory]
Error Handling Workflow
[Decryption Attempt]
|
[Parse Header] --FAIL--> [Return: Corrupt/invalid file format]
|
[Derive Key] --FAIL--> [Return: KDF parameter error]
|
[Decrypt + Verify Tag]
|
[Tag Valid?]
YES --> [Return plaintext]
NO --> [Return: Authentication failed - data tampered]
[DO NOT return partial plaintext]
Back to mukul975/Anthropic-Cybersecurity-Skills (817 security skills) or Agent skills.