前言
在移动应用开发中,敏感数据的安全存储是一个永恒的话题。无论是用户凭证、Token、还是隐私配置,都需要一种安全可靠的存储方案。flutter_secure_storage 作为 Flutter 生态中最流行的安全存储插件,支持 Android、iOS、macOS、Windows、Linux 和 Web 六大平台,为开发者提供了统一的安全存储接口。
今天我们就来深入剖析这个插件的架构设计与实现原理。
项目概览
flutter_secure_storage 是一个用于安全存储键值对数据的 Flutter 插件,GitHub 地址为 juliansteenbakker/flutter_secure_storage,目前已获得 2.7k+ Stars,支持 Dart SDK 3.3.0+ 和 Flutter 3.19.0+。
核心特性:
- 平台级安全存储:iOS/macOS 使用 Keychain,Android 使用 KeyStore + 自定义加密,Windows/Linux 使用系统凭据管理器,Web 使用 WebCrypto
- 强加密算法:Android 默认使用 RSA OAEP + AES-GCM,iOS/macOS 使用 Secure Enclave
- 生物识别支持:可选的指纹/面容认证
- 自动迁移:版本升级时自动迁移加密数据
- 跨平台统一 API:一致的 Dart 接口,平台差异化配置
核心架构
1. 插件结构
该插件采用 monorepo 架构,主要由以下子包组成:
bash
flutter_secure_storage/
├── flutter_secure_storage/ # Flutter 平台接口层
├── flutter_secure_storage_darwin/ # iOS/macOS 原生实现
├── flutter_secure_storage_linux/ # Linux 原生实现
├── flutter_secure_storage_web/ # Web 原生实现
├── flutter_secure_storage_windows/ # Windows 原生实现
└── flutter_secure_storage_platform_interface/ # 平台接口抽象
2. Dart 层核心代码
FlutterSecureStorage 是核心类,提供了统一的存储接口:
dart
class FlutterSecureStorage {
const FlutterSecureStorage({
this.iOptions = IOSOptions.defaultOptions,
this.aOptions = AndroidOptions.defaultOptions,
this.lOptions = LinuxOptions.defaultOptions,
this.wOptions = WindowsOptions.defaultOptions,
this.webOptions = WebOptions.defaultOptions,
this.mOptions = MacOsOptions.defaultOptions,
});
Future<void> write({required String key, required String? value, ...});
Future<String?> read({required String key, ...});
Future<void> delete({required String key, ...});
Future<Map<String, String>> readAll();
Future<void> deleteAll();
Future<bool> containsKey({required String key});
// 监听器功能
void registerListener({required String key, required ValueChanged<String?> listener});
}
Android 安全方案详解
1. v10.0.0 重大安全更新
2024 年的 v10.0.0 版本进行了重大安全重构,主要变更:
| 变更项 | 旧方案 | 新方案 |
|---|---|---|
| 加密库 | Jetpack Security (已弃用) | 自定义安全加密实现 |
| 密钥算法 | RSA/ECB/PKCS1 | RSA/ECB/OAEPWithSHA-256AndMGF1Padding |
| 存储算法 | AES/CBC/PKCS7Padding | AES/GCM/NoPadding |
| 最低 SDK | 19 | 23 |
| 生物识别 | 依赖 Jetpack Crypto | 原生 KeyStore 集成 |
2. 加密算法配置
AndroidOptions 提供了灵活的配置选项:
less
// 标准安全存储 (默认)
final storage = FlutterSecureStorage(
aOptions: AndroidOptions(),
);
// 可选生物识别
final storage = FlutterSecureStorage(
aOptions: AndroidOptions.biometric(
enforceBiometrics: false, // 无生物识别时优雅降级
biometricPromptTitle: '验证身份',
),
);
// 强制生物识别
final storage = FlutterSecureStorage(
aOptions: AndroidOptions.biometric(
enforceBiometrics: true, // 必须有 PIN/指纹/面容
),
);
3. 支持的加密组合
| 密钥算法 | 存储算法 | 生物识别 |
|---|---|---|
| RSA_ECB_OAEPwithSHA_256andMGF1Padding | AES_GCM_NoPadding | ❌ |
| RSA_ECB_PKCS1Padding (已弃用) | AES_CBC_PKCS7Padding (已弃用) | ❌ |
| AES_GCM_NoPadding | AES_GCM_NoPadding | ✅ |
4. 自动迁移机制
新版本支持自动迁移旧数据,通过 migrateOnAlgorithmChange 配置:
less
final storage = FlutterSecureStorage(
aOptions: AndroidOptions(
migrateOnAlgorithmChange: true, // 默认开启
migrateWithBackup: true, // 备份保护
),
);
迁移流程:
- 检测已存储数据的加密算法版本
- 创建备份数据 (
_BACKUP后缀) - 使用新算法重新加密存储
- 标记迁移进度 (
_MIGRATED) - 清理备份和进度标记
iOS/macOS 安全方案
1. Keychain 集成
iOS 和 macOS 使用系统级 Keychain 存储,通过 flutter_secure_storage_darwin 实现:
php
final storage = FlutterSecureStorage(
iOptions: IOSOptions(
accessibility: KeychainAccessibility.first_unlock,
synchronizable: true,
),
);
可访问性级别:
first_unlock:设备首次解锁后(重启后首次解锁)first_unlock_this_device:首次安装后解锁unlocked:设备解锁时(默认)when_unlocked_this_device:设备解锁且仅本设备
2. Secure Enclave 支持
v10.1.0 新增 Secure Enclave 硬件级安全支持:
less
await storage.write(
key: 'token',
value: 'secret',
iOptions: IOSOptions(
useSecureEnclave: true,
accessControlFlags: const [
AccessControlFlag.userPresence, // 需要面容/指纹/密码
],
),
);
原理:
- AES 密钥存储在 Secure Enclave 硬件中
- 无法从设备导出
- 解密需要物理设备和生物识别
Web 安全方案
Web 平台使用 WebCrypto API,实现有限但实用的安全存储:
less
final storage = FlutterSecureStorage(
webOptions: WebOptions(
wrapKey: 'your_application_key', // 应用级包装密钥
wrapKeyIv: 'your_iv', // 初始化向量
useSessionStorage: false, // true=会话存储
),
);
限制:
- 仅在 HTTPS 或 localhost 环境工作
- 加密数据绑定到同一域名
- 不可移植到其他浏览器
常见问题与解决方案
1. Android 自动备份导致异常
vbnet
java.security.InvalidKeyException: Failed to unwrap key
解决方案: 在 AndroidManifest.xml 中禁用自动备份:
ini
<application
android:allowBackup="false"
...>
</application>
2. iOS 热重载后数据丢失
某些情况下 Keychain 访问可能受限,需要在 release 模式验证。
3. Web 平台跨域问题
确保启用 HTTP Strict Transport Security:
ini
Strict-Transport-Security: max-age=31536000; includeSubDomains
最佳实践
1. 初始化时机
csharp
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
2. 敏感数据存储模式
dart
class SecureStorageService {
final _storage = FlutterSecureStorage(
aOptions: AndroidOptions(
migrateWithBackup: true, // 生产环境建议开启
),
);
Future<void> saveToken(String token) async {
await _storage.write(key: 'auth_token', value: token);
}
Future<String?> getToken() async {
return await _storage.read(key: 'auth_token');
}
}
3. 错误恢复策略
less
final storage = FlutterSecureStorage(
aOptions: AndroidOptions(
resetOnError: true, // 发生错误时重置存储
),
);
性能对比
在三星 Galaxy S21 (Android 12) 上的基准测试结果:
| 操作 | 平均耗时 |
|---|---|
| write | ~15ms |
| read | ~5ms |
| delete | ~3ms |
总结
flutter_secure_storage 为 Flutter 应用提供了企业级的安全存储解决方案:
- 安全性:使用平台原生安全机制 + 强加密算法
- 易用性:统一的 Dart API,平台差异化透明
- 可靠性:自动迁移、备份保护、优雅降级
- 跨平台:六大平台一致体验
如果你的应用需要存储任何敏感信息,这是一个值得信赖的选择。