Introduction
Advanced Encryption Standard (AES) stands as the cornerstone of modern data security, protecting everything from online banking transactions to classified government communications. Since its adoption by the National Institute of Standards and Technology (NIST) in 2001, AES has become the most widely deployed symmetric encryption algorithm worldwide, trusted by organizations ranging from Fortune 500 companies to intelligence agencies.
Understanding AES encryption is crucial for anyone working in cybersecurity, software development, or data protection. This comprehensive guide demystifies AES encryption, exploring its mathematical foundations, practical implementation strategies, security considerations, and real-world applications. Whether you’re implementing encryption in a new application, conducting security audits, or simply seeking to understand how your data is protected, this guide provides the knowledge you need.
Our AES Encryptor/Decryptor tool demonstrates these concepts in action, providing hands-on experience with military-grade encryption in a user-friendly browser interface. Throughout this guide, we’ll reference practical applications and demonstrate how theoretical cryptographic principles translate into secure, production-ready systems.
Background and Cryptographic Foundations
The Evolution of Encryption Standards
Before AES, the Data Encryption Standard (DES) protected sensitive information for nearly 25 years. However, by the late 1990s, advances in computing power made DES’s 56-bit key vulnerable to brute-force attacks. In 1997, NIST initiated a competition to find DES’s successor, ultimately selecting the Rijndael algorithm (developed by Belgian cryptographers Joan Daemen and Vincent Rijmen) as the Advanced Encryption Standard.
Timeline of Encryption Standards:
- 1977: DES adopted as federal standard (56-bit key)
- 1998: Electronic Frontier Foundation cracks DES in 56 hours
- 1998: Triple DES introduced as interim solution
- 2001: AES officially adopted by NIST
- 2003: NSA approves AES for Top Secret information
- 2025: AES remains unbroken and industry standard
How AES Works: Mathematical Foundations
AES operates as a symmetric block cipher, meaning it uses the same key for encryption and decryption and processes data in fixed-size blocks (128 bits). The algorithm supports three key sizes:
- AES-128: 128-bit keys, 10 rounds of processing
- AES-192: 192-bit keys, 12 rounds of processing
- AES-256: 256-bit keys, 14 rounds of processing
Encryption Process:
Plaintext Block (128 bits)
↓
Key Expansion (generate round keys)
↓
Initial Round
├── AddRoundKey
↓
Main Rounds (repeat 9/11/13 times)
├── SubBytes (substitution)
├── ShiftRows (permutation)
├── MixColumns (diffusion)
└── AddRoundKey
↓
Final Round
├── SubBytes
├── ShiftRows
└── AddRoundKey
↓
Ciphertext Block (128 bits)
Key Transformation Steps:
- SubBytes: Non-linear substitution using S-box (prevents pattern analysis)
- ShiftRows: Cyclic shifts of block rows (provides diffusion)
- MixColumns: Mixes data within columns (increases diffusion)
- AddRoundKey: XOR with round key (adds key-dependent transformation)
Each round makes the relationship between plaintext and ciphertext progressively more complex, creating the “avalanche effect” where changing a single input bit affects approximately half of all output bits.
Security Strength Analysis
Brute Force Resistance:
- AES-128: 2^128 possible keys (~3.4 × 10^38 combinations)
- AES-192: 2^192 possible keys (~6.2 × 10^57 combinations)
- AES-256: 2^256 possible keys (~1.1 × 10^77 combinations)
Attack Complexity:
Using a hypothetical supercomputer capable of testing 1 billion keys per second:
| Key Size | Time to Break |
|---|---|
| AES-128 | 10^21 years |
| AES-192 | 10^39 years |
| AES-256 | 10^59 years |
For context, the universe is approximately 1.4 × 10^10 years old. Even with quantum computing advances, AES-256 provides post-quantum security for decades.
Known Attacks and Mitigations:
The strongest theoretical attack against AES is the “biclique attack” (discovered 2011):
- Reduces AES-128 complexity from 2^128 to 2^126.1
- Reduces AES-256 complexity from 2^256 to 2^254.4
- Still computationally infeasible (purely theoretical)
- No practical impact on real-world security
Modes of Operation
AES is a block cipher that encrypts fixed-size blocks. To encrypt arbitrary-length data, we use modes of operation:
ECB (Electronic Codebook) - ⚠️ Not Recommended
Block 1 → AES → Ciphertext 1
Block 2 → AES → Ciphertext 2
Block 3 → AES → Ciphertext 3
Problems:
- Identical plaintext blocks produce identical ciphertext
- Reveals patterns in data (famous “ECB penguin” demonstration)
- No security against block manipulation
Use case: None for production systems
CBC (Cipher Block Chaining) - ✓ Traditional Choice
IV ⊕ Block 1 → AES → Ciphertext 1
Ciphertext 1 ⊕ Block 2 → AES → Ciphertext 2
Ciphertext 2 ⊕ Block 3 → AES → Ciphertext 3
Advantages:
- Each ciphertext block depends on all previous plaintext blocks
- Randomized with Initialization Vector (IV)
- Well-studied and proven secure
Considerations:
- Requires padding for non-block-sized data
- Sequential processing (cannot parallelize encryption)
- Vulnerable to padding oracle attacks without proper HMAC
CTR (Counter Mode) - ✓ High Performance
AES(Nonce + Counter 1) ⊕ Block 1 → Ciphertext 1
AES(Nonce + Counter 2) ⊕ Block 2 → Ciphertext 2
AES(Nonce + Counter 3) ⊕ Block 3 → Ciphertext 3
Advantages:
- Parallelizable (very fast)
- No padding required
- Random access to encrypted data
- Converts block cipher into stream cipher
Considerations:
- Never reuse nonce with same key
- No built-in authentication
GCM (Galois/Counter Mode) - ⭐ Modern Recommended
CTR Mode Encryption
+
Built-in Authentication (GMAC)
↓
Ciphertext + Authentication Tag
Advantages:
- Authenticated encryption (confidentiality + integrity)
- High performance (parallelizable)
- Detects tampering automatically
- Industry standard for TLS 1.3, SSH, IPsec
Implementation:
// GCM provides both encryption and authentication
const encrypted = AES-GCM.encrypt({
plaintext: data,
key: encryptionKey,
iv: randomIV,
additionalData: contextInfo // Optional authenticated metadata
});
// Returns: { ciphertext, authenticationTag }
Our AES Encryptor/Decryptor uses GCM mode by default for maximum security.
Implementation Workflows
Secure Encryption Workflow
Implementing AES encryption securely requires following established best practices:
Step 1: Key Generation and Management
// Generate cryptographically secure key
function generateAESKey(keySize = 256) {
const keySizeBytes = keySize / 8; // 256 bits = 32 bytes
const randomBytes = crypto.getRandomValues(new Uint8Array(keySizeBytes));
return {
raw: randomBytes,
base64: btoa(String.fromCharCode(...randomBytes)),
hex: Array.from(randomBytes).map(b => b.toString(16).padStart(2, '0')).join('')
};
}
// Derive key from password using PBKDF2
async function deriveKeyFromPassword(password, salt, iterations = 100000) {
const passwordKey = await crypto.subtle.importKey(
'raw',
new TextEncoder().encode(password),
'PBKDF2',
false,
['deriveBits', 'deriveKey']
);
const derivedKey = await crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: salt,
iterations: iterations,
hash: 'SHA-256'
},
passwordKey,
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
return derivedKey;
}
Key Generation Best Practices:
- ✅ Use cryptographically secure random number generators
- ✅ Never hardcode encryption keys in source code
- ✅ Store keys separately from encrypted data
- ✅ Use key derivation functions (KDF) for password-based encryption
- ✅ Implement key rotation policies
Step 2: Encryption Implementation
async function encryptAES_GCM(plaintext, key) {
// Generate random IV (96 bits for GCM)
const iv = crypto.getRandomValues(new Uint8Array(12));
// Encode plaintext
const encodedText = new TextEncoder().encode(plaintext);
// Encrypt
const ciphertext = await crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: iv,
tagLength: 128 // Authentication tag length in bits
},
key,
encodedText
);
// Combine IV and ciphertext for storage
const combined = new Uint8Array(iv.length + ciphertext.byteLength);
combined.set(iv, 0);
combined.set(new Uint8Array(ciphertext), iv.length);
return {
ciphertext: combined,
base64: btoa(String.fromCharCode(...combined)),
iv: btoa(String.fromCharCode(...iv))
};
}
Step 3: Decryption Implementation
async function decryptAES_GCM(encryptedData, key) {
// Extract IV and ciphertext
const combined = Uint8Array.from(atob(encryptedData), c => c.charCodeAt(0));
const iv = combined.slice(0, 12);
const ciphertext = combined.slice(12);
try {
// Decrypt and verify authentication tag
const decryptedData = await crypto.subtle.decrypt(
{
name: 'AES-GCM',
iv: iv,
tagLength: 128
},
key,
ciphertext
);
// Decode to text
return new TextDecoder().decode(decryptedData);
} catch (error) {
// Authentication tag verification failed or wrong key
throw new Error('Decryption failed: Invalid key or corrupted data');
}
}
Step 4: Error Handling and Validation
class EncryptionService {
async encrypt(plaintext, key) {
// Validate inputs
if (!plaintext || plaintext.length === 0) {
throw new Error('Plaintext cannot be empty');
}
if (!key) {
throw new Error('Encryption key required');
}
// Check key strength
const keyStrength = this.validateKeyStrength(key);
if (keyStrength.score < 60) {
console.warn('Weak encryption key detected');
}
try {
const encrypted = await encryptAES_GCM(plaintext, key);
// Log encryption event (without sensitive data)
this.logEncryptionEvent({
timestamp: new Date().toISOString(),
dataSize: plaintext.length,
keyStrength: keyStrength.score
});
return encrypted;
} catch (error) {
console.error('Encryption failed:', error.message);
throw new Error('Encryption operation failed');
}
}
async decrypt(ciphertext, key) {
// Validate inputs
if (!ciphertext || ciphertext.length === 0) {
throw new Error('Ciphertext cannot be empty');
}
if (!key) {
throw new Error('Decryption key required');
}
try {
const decrypted = await decryptAES_GCM(ciphertext, key);
// Log decryption event
this.logDecryptionEvent({
timestamp: new Date().toISOString(),
success: true
});
return decrypted;
} catch (error) {
// Log failed attempt
this.logDecryptionEvent({
timestamp: new Date().toISOString(),
success: false,
error: error.message
});
throw new Error('Decryption failed: Invalid key or corrupted data');
}
}
validateKeyStrength(key) {
// Use Password Strength Checker for validation
return checkPasswordStrength(key);
}
}
Database Field Encryption
Implementing column-level encryption for sensitive database fields:
class DatabaseEncryption {
constructor(encryptionKey) {
this.key = encryptionKey;
this.encryptionService = new EncryptionService();
}
async encryptFields(record, fieldsToEncrypt) {
const encrypted = { ...record };
for (const field of fieldsToEncrypt) {
if (record[field]) {
encrypted[field] = await this.encryptionService.encrypt(
String(record[field]),
this.key
);
}
}
return encrypted;
}
async decryptFields(record, fieldsToDecrypt) {
const decrypted = { ...record };
for (const field of fieldsToDecrypt) {
if (record[field]) {
try {
decrypted[field] = await this.encryptionService.decrypt(
record[field],
this.key
);
} catch (error) {
console.error(`Failed to decrypt field ${field}:`, error);
decrypted[field] = null;
}
}
}
return decrypted;
}
}
// Usage example
const dbEncryption = new DatabaseEncryption(process.env.DB_ENCRYPTION_KEY);
// Encrypt before storing
const user = {
id: 12345,
name: 'John Doe',
email: 'john@example.com',
ssn: '123-45-6789',
creditCard: '4532-1234-5678-9010'
};
const encryptedUser = await dbEncryption.encryptFields(user, ['ssn', 'creditCard']);
await database.users.insert(encryptedUser);
// Decrypt after retrieving
const retrievedUser = await database.users.findOne({ id: 12345 });
const decryptedUser = await dbEncryption.decryptFields(retrievedUser, ['ssn', 'creditCard']);
File Encryption System
class FileEncryptionManager {
async encryptFile(file, password) {
// Derive key from password
const salt = crypto.getRandomValues(new Uint8Array(16));
const key = await deriveKeyFromPassword(password, salt);
// Read file content
const fileContent = await file.arrayBuffer();
// Encrypt file data
const encrypted = await encryptAES_GCM(
new Uint8Array(fileContent),
key
);
// Create encrypted file structure
const encryptedFile = {
metadata: {
originalName: file.name,
originalSize: file.size,
encryptedAt: new Date().toISOString(),
algorithm: 'AES-256-GCM'
},
salt: btoa(String.fromCharCode(...salt)),
data: encrypted.base64
};
return JSON.stringify(encryptedFile);
}
async decryptFile(encryptedFileData, password) {
const encryptedFile = JSON.parse(encryptedFileData);
// Derive key using stored salt
const salt = Uint8Array.from(atob(encryptedFile.salt), c => c.charCodeAt(0));
const key = await deriveKeyFromPassword(password, salt);
// Decrypt file data
const decrypted = await decryptAES_GCM(encryptedFile.data, key);
// Reconstruct file
return new Blob([decrypted], { type: 'application/octet-stream' });
}
}
Comparison with Other Encryption Methods
Symmetric vs Asymmetric Encryption
| Aspect | AES (Symmetric) | RSA (Asymmetric) |
|---|---|---|
| Key Structure | Single shared key | Public/private key pair |
| Speed | Very fast | 100-1000x slower |
| Key Size | 128-256 bits | 2048-4096 bits |
| Use Case | Bulk data encryption | Key exchange, signatures |
| Key Distribution | Challenging (must share securely) | Easier (public key can be shared) |
| Data Size | Unlimited | Limited (key size dependent) |
Hybrid Approach (TLS, PGP):
- Use RSA to exchange AES key securely
- Use AES to encrypt actual data
- Combines security of RSA with speed of AES
Explore our RSA Key Generator to understand asymmetric encryption.
AES vs Other Symmetric Algorithms
| Algorithm | Key Size | Block Size | Speed | Security Status |
|---|---|---|---|---|
| AES | 128/192/256 | 128 bits | Fast | ✅ Secure |
| ChaCha20 | 256 bits | Stream | Very Fast | ✅ Secure |
| Blowfish | 32-448 bits | 64 bits | Fast | ⚠️ 64-bit blocks weak |
| 3DES | 168 bits | 64 bits | Slow | ⚠️ Deprecated |
| DES | 56 bits | 64 bits | Fast | ❌ Broken |
ChaCha20-Poly1305: Modern alternative to AES-GCM
- Faster on devices without AES hardware acceleration
- Used in Google’s TLS implementation
- Equally secure to AES-256-GCM
Recommendation: AES-256-GCM for most applications, ChaCha20-Poly1305 for mobile/IoT devices.
When to Use AES
Ideal Use Cases:
- ✅ Database field encryption
- ✅ File encryption
- ✅ Secure data storage
- ✅ Application configuration encryption
- ✅ Backup encryption
- ✅ Data at rest protection
Not Ideal For:
- ❌ Password hashing (use bcrypt, Argon2)
- ❌ Digital signatures (use RSA, ECDSA)
- ❌ Key exchange (use Diffie-Hellman, RSA)
- ❌ One-way transformations (use SHA-256)
For password hashing, use our Hash Generator with appropriate algorithms.
Best Practices and Security Guidelines
Key Management
Key Generation:
// Good: Cryptographically secure
const key = crypto.getRandomValues(new Uint8Array(32));
// Bad: Weak randomness
const weakKey = Math.random().toString(36).substring(2, 34);
Key Storage:
- Environment Variables (for applications):
export AES_ENCRYPTION_KEY="base64_encoded_key_here"
- Key Management Systems (for production):
- AWS KMS (Key Management Service)
- Azure Key Vault
- HashiCorp Vault
- Google Cloud KMS
- Hardware Security Modules (for high-security):
- FIPS 140-2 compliant
- Physical tamper protection
- Dedicated cryptographic processors
Key Rotation:
class KeyRotationManager {
async rotateKey(oldKey, newKey, encryptedData) {
// Decrypt with old key
const plaintext = await decrypt(encryptedData, oldKey);
// Re-encrypt with new key
const reEncrypted = await encrypt(plaintext, newKey);
// Securely delete old key
this.secureDelete(oldKey);
return reEncrypted;
}
secureDelete(key) {
// Overwrite key memory with zeros
if (key instanceof Uint8Array) {
crypto.getRandomValues(key); // Overwrite with random data
key.fill(0); // Then zero out
}
}
}
Initialization Vector (IV) Best Practices
Critical Rules:
- Never reuse IV with the same key (especially in GCM mode)
- Always use cryptographically secure random IVs
- Store IV with ciphertext (IV doesn’t need to be secret)
- Use appropriate IV size (96 bits for GCM, 128 bits for CBC)
// Good: Random IV for each encryption
function generateIV(mode) {
const size = mode === 'GCM' ? 12 : 16; // 96 or 128 bits
return crypto.getRandomValues(new Uint8Array(size));
}
// Bad: Fixed IV (catastrophic in GCM mode)
const fixedIV = new Uint8Array(12).fill(0); // NEVER DO THIS
Additional Authenticated Data (AAD)
Use AAD in GCM mode for context binding:
async function encryptWithContext(plaintext, key, context) {
const iv = crypto.getRandomValues(new Uint8Array(12));
const additionalData = new TextEncoder().encode(JSON.stringify(context));
const encrypted = await crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: iv,
additionalData: additionalData, // Authenticated but not encrypted
tagLength: 128
},
key,
new TextEncoder().encode(plaintext)
);
return { encrypted, iv, context };
}
// Usage: Bind encryption to specific context
const encrypted = await encryptWithContext(
sensitiveData,
key,
{
userId: 12345,
purpose: 'medical-record',
version: 'v2'
}
);
// Decryption will fail if context is modified
Performance Optimization
Hardware Acceleration: Modern CPUs include AES-NI (AES New Instructions):
- 4-8x faster encryption/decryption
- Available in Intel (2010+) and AMD (2012+) processors
- Automatically used by Web Crypto API
Batch Processing:
async function encryptBatch(items, key) {
// Process in parallel for better performance
const promises = items.map(item => encryptAES_GCM(item, key));
return await Promise.all(promises);
}
Chunking Large Data:
async function encryptLargeData(data, key, chunkSize = 1024 * 1024) {
const chunks = [];
for (let i = 0; i < data.length; i += chunkSize) {
const chunk = data.slice(i, i + chunkSize);
const encrypted = await encryptAES_GCM(chunk, key);
chunks.push(encrypted);
// Yield to event loop
await new Promise(resolve => setTimeout(resolve, 0));
}
return chunks;
}
Security Audit Checklist
Before deploying AES encryption:
- Using AES-256 (not AES-128) for sensitive data
- Using GCM mode (authenticated encryption)
- Generating random IVs for each encryption
- Never reusing IVs with the same key
- Storing keys separately from encrypted data
- Using cryptographically secure random number generator
- Implementing key rotation procedures
- Validating key strength (use Password Strength Checker)
- Logging encryption/decryption events (without keys)
- Implementing proper error handling
- Testing decryption before discarding old keys
- Documenting key management procedures
- Planning disaster recovery for lost keys
- Regular security audits and penetration testing
Case Study: Healthcare Data Protection Implementation
Challenge
A healthcare technology company needed to implement HIPAA-compliant encryption for patient medical records in their cloud-based system. Requirements included:
- Encryption at rest for all Protected Health Information (PHI)
- Field-level encryption for highly sensitive data (SSN, medical history)
- Key rotation every 90 days
- Audit logging for all encryption operations
- Performance supporting 10,000+ concurrent users
- Compliance with HIPAA Security Rule (45 CFR § 164.312)
Solution Architecture
Layer 1: Database Encryption
Application Layer
↓
Field-Level Encryption (AES-256-GCM)
├── Patient SSN
├── Medical History
├── Lab Results
└── Prescription Data
↓
Database Layer (PostgreSQL)
↓
Disk Encryption (AES-256-XTS)
Layer 2: Key Management
AWS KMS (Key Management Service)
├── Master Key (hardware-protected)
├── Data Encryption Keys (DEK)
│ ├── Current Active Key
│ ├── Previous Key (30-day overlap)
│ └── Archived Keys (compliance retention)
└── Key Rotation Policy (90 days)
Implementation Code:
class HealthcareEncryptionService {
constructor(kmsClient) {
this.kms = kmsClient;
this.cache = new Map(); // Key cache
}
async encryptPHI(patientData) {
// Get current data encryption key
const dek = await this.getCurrentDEK();
// Encrypt sensitive fields
const encrypted = {
id: patientData.id, // Not encrypted
name: patientData.name, // Not encrypted (searchable)
ssn: await this.encrypt(patientData.ssn, dek),
dob: await this.encrypt(patientData.dob, dek),
medicalHistory: await this.encrypt(
JSON.stringify(patientData.medicalHistory),
dek
),
metadata: {
encryptedAt: new Date().toISOString(),
keyVersion: dek.version,
algorithm: 'AES-256-GCM'
}
};
// Audit log
await this.logEncryption({
patientId: patientData.id,
timestamp: new Date().toISOString(),
keyVersion: dek.version,
fields: ['ssn', 'dob', 'medicalHistory']
});
return encrypted;
}
async decryptPHI(encryptedData) {
// Get appropriate key version
const dek = await this.getDEK(encryptedData.metadata.keyVersion);
// Decrypt sensitive fields
const decrypted = {
id: encryptedData.id,
name: encryptedData.name,
ssn: await this.decrypt(encryptedData.ssn, dek),
dob: await this.decrypt(encryptedData.dob, dek),
medicalHistory: JSON.parse(
await this.decrypt(encryptedData.medicalHistory, dek)
)
};
// Audit log
await this.logDecryption({
patientId: encryptedData.id,
timestamp: new Date().toISOString(),
keyVersion: encryptedData.metadata.keyVersion,
accessedBy: this.getCurrentUser()
});
return decrypted;
}
async rotateKeys() {
// Generate new DEK
const newDEK = await this.kms.generateDataKey();
// Mark current DEK for deprecation
await this.kms.deprecateKey(this.currentDEKId, {
overlapPeriod: 30 // days
});
// Background job: Re-encrypt all data
await this.scheduleReEncryption(this.currentDEKId, newDEK.id);
this.currentDEKId = newDEK.id;
}
}
Results
After 12 months of implementation:
- ✅ 100% HIPAA compliance across all audits
- ✅ Zero data breaches involving PHI
- ✅ <50ms encryption overhead (imperceptible to users)
- ✅ Successful key rotations every 90 days
- ✅ 500,000+ patient records securely encrypted
- ✅ Complete audit trail for compliance reporting
Key Lessons
- Defense in Depth: Multiple encryption layers (field + disk)
- Key Management is Critical: Used dedicated KMS instead of custom solution
- Performance Testing: Optimized with key caching and batch operations
- Audit Everything: Comprehensive logging enabled compliance and incident response
- Plan for Key Rotation: Automated processes prevent operational burden
Call to Action
Implement Secure Encryption Today
For Developers:
- Start using our AES Encryptor/Decryptor to understand AES encryption hands-on
- Review your current encryption implementations
- Upgrade to AES-256-GCM if using older modes
- Implement comprehensive key management
- Add encryption to your security checklist
For Security Teams:
- Conduct encryption audits across your infrastructure
- Implement organization-wide encryption standards
- Deploy key management systems
- Establish key rotation policies
- Train development teams on cryptographic best practices
For Organizations:
- Assess regulatory compliance requirements
- Identify sensitive data requiring encryption
- Select appropriate encryption tools and services
- Develop incident response plans
- Engage security consultants for complex implementations
Enhance Your Security Toolkit
Explore complementary security tools:
- Password Strength Checker: Validate encryption key strength before deployment
- Hash Generator: Implement secure password hashing alongside encryption
- RSA Key Generator: Generate key pairs for hybrid encryption systems
- UUID Generator: Create unique identifiers for encryption contexts
Continue Learning
Advanced Topics:
- Homomorphic Encryption: Computing on encrypted data
- Quantum-Resistant Cryptography: Preparing for quantum threats
- Searchable Encryption: Querying encrypted databases
- Zero-Knowledge Proofs: Privacy-preserving authentication
Stay Current:
- Follow cryptographic research publications
- Monitor NIST standards updates
- Subscribe to security vulnerability databases
- Participate in cryptography conferences
External References
-
NIST FIPS 197: Advanced Encryption Standard (AES) specification. National Institute of Standards and Technology. https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf
-
NIST SP 800-38D: Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
-
Web Crypto API Specification: W3C Recommendation for cryptographic operations in web applications. https://www.w3.org/TR/WebCryptoAPI/
-
“The Design of Rijndael: AES - The Advanced Encryption Standard” by Joan Daemen and Vincent Rijmen. Springer, 2002. Comprehensive technical documentation of the AES algorithm.
Last updated: November 3, 2025 | Article ID: aes-encryptor-decryptor-guide | Gray-wolf Tools Security Division