init method
Initialize the secure storage Must be called before using any storage operations
Automatically detects app reinstallation and clears old secure storage data
enableCache - Enable in-memory caching for frequently accessed data
Throws SecureStorageException if initialization fails
Implementation
Future<void> init({bool enableCache = false}) async {
if (_initialized) return;
await _withLock(() async {
if (_initialized) return; // Double-check after acquiring lock
try {
// Check if app was reinstalled and clear old secure storage data
await _checkAndClearOnReinstall();
// Get or create encryption key
String? savedKey = await _secureStorage.read(key: _keyIdentifier);
if (savedKey == null) {
// Generate new key on first launch
_key = encrypt.Key.fromSecureRandom(32);
savedKey = base64Url.encode(_key.bytes);
await _secureStorage.write(key: _keyIdentifier, value: savedKey);
// Set initial version
await _secureStorage.write(
key: _versionKey,
value: _currentVersion.toString(),
);
} else {
// Load existing key
final keyBytes = base64Url.decode(savedKey);
// Validate key length (must be 16, 24, or 32 bytes)
if (keyBytes.length == 16 || keyBytes.length == 24 || keyBytes.length == 32) {
_key = encrypt.Key(keyBytes);
// Check version and migrate if needed
await _checkAndMigrateVersion();
} else {
// Key is corrupted - regenerate it
_key = encrypt.Key.fromSecureRandom(32);
savedKey = base64Url.encode(_key.bytes);
await _secureStorage.write(key: _keyIdentifier, value: savedKey);
// Reset version since we are starting fresh with a new key
await _secureStorage.write(
key: _versionKey,
value: _currentVersion.toString(),
);
}
}
_initialized = true;
} catch (e) {
throw SecureStorageException(
'Failed to initialize SecureStorageUtil',
e,
);
}
});
}