SecurePrefsPlus
A secure storage solution combining SharedPreferences with AES-256-GCM encryption for Flutter. Pure Dart implementation with full cross-platform support including web.
Features
✅ Military-grade encryption - AES-256-GCM encryption
✅ Pure Dart - No native dependencies, works everywhere
✅ Cross-platform - iOS, Android, Web, Windows, macOS, Linux
✅ Simple API - Familiar SharedPreferences-like interface
✅ Type-safe - Support for String, int, double, bool, and List
Installation
Add to your pubspec.yaml
:
dependencies:
secure_prefs_plus: ^1.0.0
Then run:
flutter pub get
Usage
Basic Example
import 'package:secure_prefs_plus/secure_prefs_plus.dart';
// Initialize with your encryption key
final prefs = await SecurePrefsPlus.getInstance(
encryptionKey: 'your-secret-encryption-key',
);
// Store encrypted data
await prefs.setString('username', 'john_doe');
await prefs.setInt('age', 25);
await prefs.setBool('isLoggedIn', true);
await prefs.setDouble('balance', 1234.56);
await prefs.setStringList('tags', ['flutter', 'dart', 'security']);
// Retrieve encrypted data
String? username = prefs.getString('username');
int? age = prefs.getInt('age');
bool? isLoggedIn = prefs.getBool('isLoggedIn');
double? balance = prefs.getDouble('balance');
List<String>? tags = prefs.getStringList('tags');
// Check if key exists
if (prefs.containsKey('username')) {
print('Username exists!');
}
// Remove a key
await prefs.remove('username');
// Get all keys
Set<String> keys = prefs.getKeys();
// Clear all data
await prefs.clear();
Advanced Usage
Custom Salt for Key Derivation
final prefs = await SecurePrefsPlus.getInstance(
encryptionKey: 'my-password',
salt: 'custom-salt-for-kdf',
);
Storing Sensitive Tokens
// Perfect for storing API tokens, session data, etc.
await prefs.setString('auth_token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...');
await prefs.setString('refresh_token', 'refresh_token_here');
// Retrieve when needed
String? token = prefs.getString('auth_token');
User Settings with Encryption
class UserSettings {
final SecurePrefsPlus _prefs;
UserSettings(this._prefs);
Future<void> saveUserData({
required String email,
required String apiKey,
}) async {
await _prefs.setString('user_email', email);
await _prefs.setString('api_key', apiKey);
}
String? getUserEmail() => _prefs.getString('user_email');
String? getApiKey() => _prefs.getString('api_key');
}
Security Features
AES-256-GCM Encryption
SecurePrefsPlus uses AES-256 in GCM (Galois/Counter Mode) which provides:
- Confidentiality - Data is encrypted with 256-bit keys
- Integrity - Built-in authentication prevents tampering
- Performance - Fast encryption/decryption even on mobile devices
Key Derivation
Your encryption key is processed using PBKDF2 with SHA-256:
- 10,000 iterations - Protects against brute-force attacks
- Custom salt support - Add your own salt for additional security
- Deterministic - Same key always produces same encryption
No Plain Text Storage
All data is encrypted before being stored in SharedPreferences. Even if someone gains access to the device storage, they cannot read your data without the encryption key.
Platform Support
Platform | Supported | Notes |
---|---|---|
iOS | ✅ | Fully supported |
Android | ✅ | Fully supported |
Web | ✅ | Uses localStorage with encryption |
Windows | ✅ | Fully supported |
macOS | ✅ | Fully supported |
Linux | ✅ | Fully supported |
Best Practices
1. Secure Your Encryption Key
// ❌ BAD - Hardcoded key
final prefs = await SecurePrefsPlus.getInstance(
encryptionKey: 'hardcoded-key-123',
);
// ✅ GOOD - Use environment variables or secure key storage
final encryptionKey = const String.fromEnvironment('ENCRYPTION_KEY');
final prefs = await SecurePrefsPlus.getInstance(
encryptionKey: encryptionKey,
);
2. Different Keys for Different Users
// Use user-specific keys
final userId = getCurrentUserId();
final prefs = await SecurePrefsPlus.getInstance(
encryptionKey: 'base-key',
salt: 'user-$userId',
);
3. Handle Exceptions
try {
final value = prefs.getString('sensitive_data');
print(value);
} on EncryptionException catch (e) {
print('Decryption failed: $e');
// Handle corrupted data or wrong key
}
4. Clear Data on Logout
Future<void> logout() async {
final prefs = await SecurePrefsPlus.getInstance(
encryptionKey: userEncryptionKey,
);
await prefs.clear();
}
API Reference
Initialization
static Future<SecurePrefsPlus> getInstance({
String encryptionKey = 'default_key_change_me',
String? salt,
})
Storage Methods
Future<bool> setString(String key, String value)
String? getString(String key)
Future<bool> setInt(String key, int value)
int? getInt(String key)
Future<bool> setDouble(String key, double value)
double? getDouble(String key)
Future<bool> setBool(String key, bool value)
bool? getBool(String key)
Future<bool> setStringList(String key, List<String> value)
List<String>? getStringList(String key)
Management Methods
Future<bool> remove(String key)
bool containsKey(String key)
Future<bool> clear()
Set<String> getKeys()
Future<void> reload()
Performance
Encryption/decryption is fast enough for typical mobile use cases:
- String (100 chars): ~1-2ms
- Int/Double/Bool: ~1ms
- List: ~2-3ms
Benchmarks on iPhone 12 Pro
Comparison with Alternatives
Feature | SecurePrefsPlus | flutter_secure_storage | encrypted_shared_preferences |
---|---|---|---|
Pure Dart | ✅ | ❌ (Native) | ❌ (Native) |
Web Support | ✅ | ❌ | ❌ |
Type Safety | ✅ | ⚠️ (String only) | ✅ |
Setup Required | ❌ | ✅ (iOS Keychain) | ✅ (Android) |
Encryption | AES-256-GCM | Platform-dependent | AES-256-CBC |
Limitations
- Not for large data - Designed for preferences and tokens, not large files
- Key management - You're responsible for managing encryption keys securely
- No biometric - Doesn't integrate with device biometrics (use flutter_secure_storage for that)
Contributing
Contributions are welcome! Please read our Contributing Guide first.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- 📧 Email: your.email@example.com
- 🐛 Issues: GitHub Issues
- 📖 Documentation: API Docs
Changelog
See CHANGELOG.md for version history.
Made with ❤️ for the Flutter community