Skip to main content

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 (the package requires Node 24.13 or later). Two algorithms are available:

  • AES-GCM (default) — authenticated encryption (AEAD).
  • AES-CBC — authenticated via Encrypt-then-MAC (HMAC-SHA256 over iv ‖ ciphertext, with a separate domain-separated key, verified before decrypt).

Quick Start​

import { defineStorage } from 'strata-storage';

// Enable encryption globally
const storage = defineStorage({
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 PBKDF2 key derivation and AES work to each encrypted write and read; measure the cost with your data and device.
  • If you enable both compression and encryption, Strata Storage compresses before encrypting.
  • Encrypt only the values that need it.

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({
type: 'user'
}, {
encryptionPassword: password
});

See Also​