Flutter中如何加密隐藏sqflite数据库保障存储安全
核心结论
- sqflite本身无默认加密、默认隐藏能力,默认配置下数据库为明文存储,且在iOS上会出现在「文件」App的应用目录下,属于预期行为,不是包本身的bug。
- 未越狱iOS设备上,其他第三方应用默认无法跨沙盒访问你的数据库文件,你看到的可编辑权限是设备持有者的本地访问权限,但设备被他人持有、越狱、备份泄露时,明文数据库存在数据泄露、被篡改的风险。
具体修复方案
一、隐藏数据库:禁止在系统「文件」App中暴露
默认sqflite创建的数据库会存放在应用沙盒的Documents目录,iOS系统默认会将该目录下的内容开放给「文件」App、iTunes文件分享访问,做两步配置即可隐藏:
- 修改iOS工程
Info.plist配置:- 把
UIFileSharingEnabled(iTunes文件分享开关)值设为NO - 把
LSSupportsOpeningDocumentsInPlace(本地文档打开支持)值设为NO
- 把
- 调整数据库存储路径到沙盒Library目录,该目录不会被系统对外暴露,借助path_provider获取路径即可,参考代码:
import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; import 'package:sqflite/sqflite.dart'; Future<Database> initHiddenDB() async { // 获取沙盒Library目录,该目录不会出现在文件App中 final libraryDir = await getLibraryDirectory(); final dbPath = p.join(libraryDir.path, 'db_name.db'); return openDatabase( dbPath, version: 1, onCreate: (db, version) { // 原有建表逻辑不需要改动 }, ); }
配置完成后,普通用户就无法在「文件」App路径下找到你的数据库文件了。
二、数据库加密:从根本上防止数据泄露、篡改
路径隐藏只是降低普通用户的访问概率,无法对抗越狱设备、沙盒备份导出后的文件访问,要彻底解决安全问题必须做数据库全量加密:
- 直接替换原版sqflite为
sqflite_sqlcipher,该包基于SQLCipher实现,API和原版sqflite完全兼容,打开数据库时传入自定义加密密钥即可,所有落盘数据全量加密,无密钥即使拿到db文件也无法读取、修改内容。 - 参考代码:
import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; // 注意:引入加密版后需要移除原版sqflite的依赖,避免类名冲突 import 'package:sqflite_sqlcipher/sqflite.dart'; Future<Database> initEncryptedDB() async { final libraryDir = await getLibraryDirectory(); final dbPath = p.join(libraryDir.path, 'db_name.db'); return openDatabase( dbPath, // 加密密钥不要硬编码在代码中,建议用flutter_secure_storage等基于系统安全区的组件存储 password: 'your_custom_strong_encryption_key', version: 1, onCreate: (db, version) { // 原有建表、CRUD逻辑和原版sqflite完全一致,不需要额外修改 }, ); }
- 额外提醒:不要把加密密钥硬编码在Dart代码里,密钥可以在应用首次启动时随机生成,存到系统Keychain(iOS)/Keystore(Android)中,避免被反编译获取密钥。
内容的提问来源于stack exchange,提问作者blue492
相关产品推荐
相关产品推荐

