Unified secure storage with built-in encryption and pluggable backends
dart pub add philiprehberger_secure_storeUnified secure storage with built-in encryption and pluggable backends
Add to your pubspec.yaml:
dependencies:
philiprehberger_secure_store: ^0.4.0
Then run:
dart pub get
import 'package:philiprehberger_secure_store/secure_store.dart';
final store = SecureStore(encryptionKey: 'my-secret-key');
await store.write('token', 'eyJhbGciOiJIUzI1...');
final token = await store.read('token');
await store.writeJson('user', {'name': 'Alice', 'role': 'admin'});
final user = await store.readJson('user');
print(user!['name']); // Alice
await store.writeBool('dark_mode', true);
await store.writeInt('login_count', 42);
final darkMode = await store.readBool('dark_mode'); // true
final count = await store.readInt('login_count'); // 42
For non-web platforms, import the file backend separately:
import 'package:philiprehberger_secure_store/secure_store.dart';
import 'package:philiprehberger_secure_store/file_backend.dart';
final store = SecureStore(
encryptionKey: 'my-key',
backend: FileBackend('/path/to/storage.json'),
);
await store.write('token', 'secret');
// Data persists across restarts
Implement StorageBackend for any storage system:
class MyDatabaseBackend implements StorageBackend {
@override
Future<String?> read(String key) async { /* ... */ }
@override
Future<void> write(String key, String value) async { /* ... */ }
// ... implement all methods
}
final store = SecureStore(
encryptionKey: 'key',
backend: MyDatabaseBackend(),
);
await store.writeMultiple({'token': 'abc', 'refresh': 'xyz', 'user': 'alice'});
final results = await store.readMultiple(['token', 'refresh']);
// {'token': 'abc', 'refresh': 'xyz'}
await store.writeWithExpiry('session', 'token123', Duration(hours: 1));
await store.isExpired('session'); // false
// Clean up all expired entries
final removed = await store.cleanExpired();
await store.containsKey('token'); // true
await store.allKeys(); // ['token', 'user', ...]
await store.delete('token');
await store.clear(); // remove everything
// Strict access — throws if key missing
final value = await store.readOrThrow('token');
// Quick key count
final count = await store.keyCount;
Re-encrypt all stored values under a new encryption key:
await store.rotateKey('new-secret-key');
// All existing values are now encrypted with the new key
Isolate groups of keys with a namespace prefix:
final settings = store.namespace('settings');
final cache = store.namespace('cache');
await settings.write('theme', 'dark');
await cache.write('data', 'value');
// Each namespace is isolated
final keys = await settings.allKeys(); // ['theme']
await cache.clear(); // only clears cache keys
// Remove all keys matching a pattern
final removed = await store.deleteWhere((key) => key.startsWith('temp_'));
// Export raw encrypted data
final data = await store.backup();
// Restore from backup (clears store first)
await store.restore(data);
// JSON-based export/import
final jsonStr = await store.export();
await store.import(jsonStr);
SecureStore| Method | Description |
|---|---|
SecureStore(encryptionKey:, backend:) | Create with encryption key and optional backend |
.write(key, value) | Store an encrypted string |
.read(key) | Read and decrypt a string (null if missing) |
.writeJson(key, value) | Store an encrypted JSON object |
.readJson(key) | Read and decrypt a JSON object |
.writeBool(key, value) | Store an encrypted boolean |
.readBool(key) | Read a boolean |
.writeInt(key, value) | Store an encrypted integer |
.readInt(key) | Read an integer |
.delete(key) | Delete a key |
.containsKey(key) | Check if a key exists |
.allKeys() | List all stored keys |
.clear() | Delete all data |
.readOrThrow(key) | Read or throw KeyNotFoundError |
.writeMultiple(pairs) | Write multiple key-value pairs |
.readMultiple(keys) | Read multiple keys at once |
.writeWithExpiry(key, value, ttl) | Store with time-to-live |
.isExpired(key) | Check if an item has expired |
.cleanExpired() | Remove all expired items |
.rotateKey(newKey) | Re-encrypt all values with a new key |
.backup() | Export raw encrypted key-value pairs |
.restore(data) | Clear and restore from raw encrypted data |
.export() | Export store as a JSON string |
.import(json) | Clear and import from a JSON string |
.keyCount | Get the number of stored keys |
.deleteWhere(test) | Delete keys matching a predicate |
.namespace(prefix) | Get a namespaced view of the store |
| Backend | Description |
|---|---|
MemoryBackend | In-memory (default, for testing) |
FileBackend(path) | JSON file on disk |
NamespacedStore | Scoped view with prefixed keys |
StorageBackend | Abstract interface for custom backends |
dart pub get
dart analyze --fatal-infos
dart test
If you find this project useful: