You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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]);
}

踩坑提醒:

  1. 加密数据库一旦创建,后续打开必须传入正确密码,密码错误会直接报数据库损坏类错误,没有破解后门,密码一定要妥善存储
  2. 禁止把数据库密码硬编码在Dart代码中,发布后的安装包可以通过反编译拿到硬编码字符串,加密会直接失效
  3. 如果要把已有的未加密sqflite数据库转为加密库,需要先打开原库导出全量数据,新建加密库后再导入,不能直接给现成的未加密库追加密码
  4. 如果从普通sqflite迁移到sqflite_sqlcipher,只需要替换导包路径、打开数据库时传入password参数即可,原有业务CRUD代码不需要改动

内容的提问来源于stack exchange,提问作者pooja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 10:51:21