Flutter应用如何使用sqflite_sqlcipher加密SQLite数据库
Flutter 集成sqflite_sqlcipher实现SQLite加密落地示例
以下是可直接跑通的实现流程,和普通sqflite的使用差异极小:
- 第一步:添加项目依赖
在项目根目录的pubspec.yaml中添加以下依赖,执行flutter pub get拉取包:
dependencies: flutter: sdk: flutter sqflite_sqlcipher: ^3.0.0 path: ^1.8.3 flutter_secure_storage: ^9.0.0 # 用于安全存储数据库密码,不建议硬编码密码
- 第二步:加密数据库初始化逻辑
SQLCipher的加密是在数据库文件创建/打开时生效的,核心区别是打开数据库时必须传入加密密码,后续所有落盘数据会自动加解密,业务层无感知。
import 'dart:math'; import 'package:path/path.dart'; import 'package:sqflite_sqlcipher/sqflite.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; const String _dbName = 'app_protected.db'; const int _dbVersion = 1; const _secureStorage = FlutterSecureStorage(); Future<Database> getEncryptedDb() async { // 拼接数据库完整存储路径 final dbDir = await getDatabasesPath(); final dbFullPath = join(dbDir, _dbName); // 首次启动生成随机强密码,存入系统级安全存储,避免硬编码泄露 String? dbPassword = await _secureStorage.read(key: 'db_encrypt_key'); if (dbPassword == null) { final secureRandom = Random.secure(); dbPassword = List.generate(32, (_) => secureRandom.nextInt(256).toRadixString(16)).join(); await _secureStorage.write(key: 'db_encrypt_key', value: dbPassword); } // 打开加密数据库,必须传入password参数 final database = await openDatabase( dbFullPath, version: _dbVersion, password: dbPassword, onCreate: (db, version) async { // 建表逻辑和普通sqflite完全一致 await db.execute(''' CREATE TABLE local_note ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, content TEXT, update_time INTEGER NOT NULL ) '''); }, onUpgrade: (db, oldVersion, newVersion) { // 数据库升级逻辑和普通sqflite无差异 }, ); return database; }
- 第三步:业务层CRUD调用
数据库打开后,所有增删改查API和原生sqflite完全一致,不需要额外加解密逻辑:
// 插入数据 Future<int> addNote(Map<String, dynamic> noteData) async { final db = await getEncryptedDb(); return db.insert('local_note', noteData); } // 查询数据 Future<List<Map<String, dynamic>>> getAllNotes() async { final db = await getEncryptedDb(); return db.query('local_note', orderBy: 'update_time DESC'); } // 删除数据 Future<int> deleteNote(int noteId) async { final db = await getEncryptedDb(); return db.delete('local_note', where: 'id = ?', whereArgs: [noteId]); }
踩坑提醒:
- 加密数据库一旦创建,后续打开必须传入正确密码,密码错误会直接报数据库损坏类错误,没有破解后门,密码一定要妥善存储
- 禁止把数据库密码硬编码在Dart代码中,发布后的安装包可以通过反编译拿到硬编码字符串,加密会直接失效
- 如果要把已有的未加密sqflite数据库转为加密库,需要先打开原库导出全量数据,新建加密库后再导入,不能直接给现成的未加密库追加密码
- 如果从普通sqflite迁移到sqflite_sqlcipher,只需要替换导包路径、打开数据库时传入password参数即可,原有业务CRUD代码不需要改动
内容的提问来源于stack exchange,提问作者pooja
相关产品推荐
相关产品推荐

