Encryption Guide
Complete guide for using encryption features in Strata Storage.
Overview
Strata Storage provides built-in authenticated encryption using the Web Crypto
API (globalThis.crypto.subtle) — the same code path on web, Capacitor webviews,
and Node.js / SSR (Node 20+). Two algorithms are available:
AES-GCM(default) — authenticated encryption (AEAD).AES-CBC— authenticated via Encrypt-then-MAC (HMAC-SHA256 overiv ‖ ciphertext, with a separate domain-separated key, verified before decrypt).
Quick Start
import { Strata } from 'strata-storage';
// Enable encryption globally
const storage = new Strata({
encryption: {
enabled: true,
password: 'your-secure-password'
}
});
// Or per operation
await storage.set('sensitive', data, {
encrypt: true,
encryptionPassword: 'specific-password'
});
Encryption Configuration
interface EncryptionConfig {
enabled?: boolean; // Enable encryption by default (storage-level)
password?: string; // Default password (storage-level)
algorithm?: 'AES-GCM' | 'AES-CBC'; // Encryption algorithm (default: 'AES-GCM')
keyLength?: 128 | 192 | 256; // AES key length in bits (default: 256)
keyDerivation?: 'PBKDF2'; // Key derivation function (only PBKDF2)
iterations?: number; // PBKDF2 iterations (default: 600000)
saltLength?: number; // Salt length in bytes (default: 16)
}
PBKDF2 iterations default to 600,000 (OWASP guidance for PBKDF2-HMAC-SHA256). The per-record iteration count is stored with each ciphertext and used on decrypt, so raising the default never breaks older data.
Usage Examples
Basic Encryption
// Encrypt specific data
await storage.set('api_key', secretKey, {
encrypt: true
});
// Retrieve and auto-decrypt
const key = await storage.get('api_key');
Custom Password
// Use different passwords for different data
await storage.set('user_data', userData, {
encrypt: true,
encryptionPassword: userPassword
});
await storage.set('admin_data', adminData, {
encrypt: true,
encryptionPassword: adminPassword
});
Handling Decryption
// Skip decryption
const encrypted = await storage.get('secret', {
skipDecryption: true
});
console.log(encrypted); // Raw encrypted data
// Ignore decryption errors
const data = await storage.get('secret', {
ignoreDecryptionErrors: true
});
// Returns null if decryption fails
Security Best Practices
1. Password Management
class SecurePasswordManager {
// Generate strong passwords
generatePassword(): string {
return storage.generatePassword(32);
}
// Derive from user input
async derivePassword(userInput: string, salt: string) {
const hash = await storage.hash(userInput + salt);
return hash;
}
}
2. Key Rotation
class KeyRotation {
async rotateEncryptionKey(oldPassword: string, newPassword: string) {
// Get all encrypted items
const keys = await storage.keys();
for (const key of keys) {
// Decrypt with old password
const value = await storage.get(key, {
encryptionPassword: oldPassword
});
if (value !== null) {
// Re-encrypt with new password
await storage.set(key, value, {
encrypt: true,
encryptionPassword: newPassword
});
}
}
}
}
3. Secure Storage Combination
// Combine encryption with secure storage on mobile
await storage.set('highly_sensitive', data, {
storage: 'secure', // Use Keychain/Keystore
encrypt: true // Additional encryption layer
});
Platform Considerations
Web Platform
- Uses Web Crypto API
- Requires HTTPS in production
- SubtleCrypto not available in insecure contexts
iOS Platform
- Can combine with Keychain for key storage
- Hardware encryption available
- Biometric protection possible
Android Platform
- Android Keystore integration
- Hardware-backed keys on supported devices
- Fingerprint/PIN protection
Error Handling
import { EncryptionError } from 'strata-storage';
try {
await storage.get('encrypted_data');
} catch (error) {
if (error instanceof EncryptionError) {
console.error('Decryption failed:', error.message);
// Handle wrong password, corrupted data, etc.
}
}
Performance Impact
- Encryption adds ~5-10ms for small data
- Scales linearly with data size
- Consider compression before encryption
- Use selective encryption for optimal performance
Advanced Usage
Custom Encryption
// Implement custom encryption adapter
class CustomEncryption {
async encrypt(data: string, password: string): Promise<EncryptedData> {
// Custom implementation
}
async decrypt(encrypted: EncryptedData, password: string): Promise<string> {
// Custom implementation
}
}
Encrypted Queries
// Query encrypted data (requires decryption)
const results = await storage.query({
'value.type': 'user'
}, {
encryptionPassword: password
});