Encryption
Magic's Crypt facade wraps AES-256-CBC encryption and decryption behind a simple API, while the Vault facade stores sensitive values in the platform's native secure storage.
On this page
Introduction#
Magic provides encryption services for securing sensitive data. The Crypt facade provides easy-to-use encryption and decryption methods, while the Vault facade provides secure storage using the platform's native secure storage (Keychain on iOS, Keystore on Android).
Configuration#
Application Key#
Magic's encrypter uses the application key defined in your .env file:
APP_KEY=base64:your-32-character-random-key-here
Generate a new key using the CLI:
dart run magic:artisan key:generate
Using The Encrypter#
Encrypting Values#
final encrypted = Crypt.encrypt('my secret data');
// Returns encrypted string
Decrypting Values#
final decrypted = Crypt.decrypt(encrypted);
// Returns: 'my secret data'
Encrypting Objects#
You can encrypt any JSON-serializable data:
final encrypted = Crypt.encrypt({
'user_id': 1,
'permissions': ['read', 'write'],
'expires': Carbon.now().addHours(1).toIso8601String(),
});
final data = Crypt.decrypt(encrypted);
// Returns the original Map
Error Handling#
try {
final decrypted = Crypt.decrypt(invalidString);
} on MagicDecryptException catch (e) {
// Handle decryption failure
print('Failed to decrypt: $e');
}
Vault (Secure Storage)#
The Vault facade provides secure storage using the platform's native secure storage mechanisms:
- iOS: Keychain
- Android: Keystore / EncryptedSharedPreferences
- Web: Encrypted localStorage (less secure)
Storing Values#
await Vault.put('api_token', 'secret-token-value');
await Vault.put('refresh_token', 'refresh-token-value');
Retrieving Values#
final token = await Vault.get('api_token');
if (token != null) {
// Use the token
}
Checking Existence#
if (await Vault.has('api_token')) {
// Token exists
}
Deleting Values#
await Vault.delete('api_token');
Clearing All Values#
await Vault.deleteAll();
Use Cases#
Authentication Tokens:
class AuthService {
Future<void> storeTokens(String token, String refreshToken) async {
await Vault.put('auth_token', token);
await Vault.put('refresh_token', refreshToken);
}
Future<String?> getToken() async {
return await Vault.get('auth_token');
}
Future<void> clearTokens() async {
await Vault.delete('auth_token');
await Vault.delete('refresh_token');
}
}
Sensitive User Data:
// Store sensitive settings
await Vault.put('pin_code', hashedPin);
await Vault.put('biometric_key', biometricData);
// API keys
await Vault.put('stripe_key', stripePublishableKey);
Encryption vs Vault#
| Feature | Crypt | Vault |
|---|---|---|
| Use Case | Encrypt data for transmission | Store secrets locally |
| Persistence | None (just transforms data) | Persistent secure storage |
| Platform | Cross-platform | Platform-specific secure storage |
| Example | Encrypt payload before API call | Store auth tokens |