Flutter数据库加密插件sqlcipher_library_windows的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter数据库加密插件sqlcipher_library_windows的使用

SQLCipher(SQLite3) V4.5.0库 for Windows X64

这个包帮助你将SQLCipher(SQLite3)库打包到你的应用程序中。它最初是为与SQLite3 with SQLCipher一起使用而开发的。

依赖项

要使SQLCipher正常工作,需要与OpenSSL 64位库(libcrypto-1_1-x64.dlllibssl-1_1-x64.dll)一起使用。这些库会自动复制到主Flutter程序的附近,以便与sqlcipher.dll动态链接。

你也可以将这两个DLL文件复制到你选择的Windows PATH目录中。

如何与SQLite3包一起使用

在Windows上使用SQLCipher时,你需要覆盖默认的打开函数,并提供由该包提供的openSQLCipherOnWindows函数:

import 'package:sqlite3/open.dart';
import 'package:sqlcipher_library_windows/sqlcipher_library_windows.dart';

// 覆盖Windows上的默认打开函数
open.overrideFor(OperatingSystem.windows, openSQLCipherOnWindows);

错误处理

如果你在运行时遇到错误,请确保:

  • 你正在使用64位Windows版本。
  • 使用Process Monitor查找有关错误的详细信息(例如,找不到某个DLL文件)。

完整示例Demo

以下是一个完整的示例,展示了如何在Flutter应用程序中使用sqlcipher_library_windows插件来创建和操作加密的SQLite数据库。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:sqlcipher_library_windows/sqlcipher_library_windows.dart';
import 'package:sqlite3/open.dart';
import 'package:sqlite3/sqlite3.dart' as sql;
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late sql.Database _db;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            OutlinedButton(
              onPressed: testSQLCipherOnWindows, 
              child: Text("Test")
            )
          ],
        ),
      ),
    );
  }

  /// 创建加密数据库
  void testSQLCipherOnWindows() async {
    if (Platform.isWindows == false) {
      return;
    } else {
      // 覆盖Windows上的默认打开函数
      open.overrideFor(OperatingSystem.windows, openSQLCipherOnWindows);
    }

    // 设置数据库密码
    final String password = "test";

    // 获取应用文档目录路径
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path;
    String filename = "$appDocPath${Platform.pathSeparator}testDB.sqlite";

    // 打开或创建数据库
    _db = sql.sqlite3.open(filename, mode: sql.OpenMode.readWriteCreate);
    if (_db.handle.address > 0) {
      print("Database created here: $filename");
      _db.execute("PRAGMA key = '$password'"); // 设置数据库密码
      print("Database password set: $password");
    }

    // 获取SQLite和SQLCipher版本
    getVersion();

    // 创建表结构
    createSchema();

    // 插入数据
    insertRows();

    // 读取数据
    readRows();
  }

  /// 创建表结构
  void createSchema() {
    _db.execute('''
      CREATE TABLE IF NOT EXISTS artists (
        id INTEGER NOT NULL PRIMARY KEY,
        name TEXT NOT NULL
      );
    ''');
  }

  /// 插入数据
  void insertRows() {
    final dynamic stmt = _db.prepare('INSERT INTO artists (name) VALUES (?)');
    stmt
      ..execute(['The Beatles'])
      ..execute(['Led Zeppelin'])
      ..execute(['The Who'])
      ..execute(['Nirvana']);
    stmt.dispose(); // 释放资源
  }

  /// 读取数据
  void readRows() {
    final sql.ResultSet resultSet = _db.select('SELECT * FROM artists WHERE name LIKE ?', ['The %']);
    resultSet.forEach((element) {
      print(element);
    });
    for (final sql.Row row in resultSet) {
      print('Artist[id: ${row['id']}, name: ${row['name']}]');
    }
  }

  /// 获取SQLite和SQLCipher版本
  void getVersion() {
    final sql.ResultSet sqliteVersion = _db.select("SELECT sqlite_version()");
    sqliteVersion.forEach((element) {
      print("SQLite Version: $element");
    });

    final sql.ResultSet cipherVersion = _db.select("PRAGMA cipher_version");
    cipherVersion.forEach((element) {
      print("SQLCipher Version: $element");
    });
  }
}

更多关于Flutter数据库加密插件sqlcipher_library_windows的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据库加密插件sqlcipher_library_windows的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用sqlcipher_library_windows插件对数据库进行加密的示例代码。这个插件是sqlcipher的Flutter封装,它允许你在Windows平台上使用加密的SQLite数据库。

首先,确保你的Flutter项目已经配置好,并且已经添加了sqlcipher_flutter_libs依赖(这个依赖通常包含了对不同平台的支持,包括Windows)。

  1. pubspec.yaml中添加依赖
dependencies:
  flutter:
    sdk: flutter
  sqlcipher_flutter_libs: ^x.y.z  # 替换为最新版本号
  1. 配置Windows平台

确保你的CMakeLists.txt(如果你使用的是CMake)或者你的Windows项目文件正确配置了sqlcipher的库文件。不过,由于sqlcipher_flutter_libs已经为你处理了大部分配置工作,你可能不需要手动配置太多。

  1. 初始化并加密数据库

下面是一个简单的示例,展示了如何初始化sqlcipher并使用它加密和解密数据库。

import 'package:flutter/material.dart';
import 'package:sqlcipher_flutter_libs/sqlcipher_flutter_libs.dart';
import 'dart:typed_data/uint8list.dart';
import 'dart:async';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('SQLCipher Flutter Example'),
        ),
        body: Center(
          child: DatabaseExample(),
        ),
      ),
    );
  }
}

class DatabaseExample extends StatefulWidget {
  @override
  _DatabaseExampleState createState() => _DatabaseExampleState();
}

class _DatabaseExampleState extends State<DatabaseExample> {
  String _status = "Initializing...";

  @override
  void initState() {
    super.initState();
    _initializeDatabase().then((_) {
      setState(() {
        _status = "Database Initialized and Encrypted";
      });
    }).catchError((error) {
      setState(() {
        _status = "Error: ${error.toString()}";
      });
    });
  }

  Future<void> _initializeDatabase() async {
    // 初始化 SQLCipher 库
    await SqlCipher().initialize();

    // 加密密钥
    Uint8List key = Uint8List.fromList("my_secret_key_123456".codeUnits);

    // 数据库路径
    String dbPath = "encrypted_database.db";

    // 打开数据库(如果数据库不存在,它将被创建)
    var database = await SqlCipher.openDatabase(dbPath, key: key);

    // 执行一个简单的事务来创建表并插入数据
    await database.transaction((txn) async {
      var batch = txn.batch();
      batch.execute("CREATE TABLE IF NOT EXISTS Test (id INTEGER PRIMARY KEY, name TEXT)");
      batch.execute("INSERT INTO Test (name) VALUES ('Alice')");
      batch.execute("INSERT INTO Test (name) VALUES ('Bob')");
      await batch.commit();
    });

    // 查询数据
    var results = await database.rawQuery("SELECT * FROM Test");
    print("Query Results: ${results.map((row) => row.columns).toList()}");

    // 关闭数据库
    await database.close();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text(_status),
      ],
    );
  }
}

注意事项

  • 替换"my_secret_key_123456"为你的实际加密密钥。密钥的长度和复杂性对于数据库的安全性至关重要。
  • 确保你的密钥管理策略是安全的,避免在代码中硬编码密钥,尤其是在生产环境中。
  • 上述代码仅作为示例,实际项目中应该包含更多的错误处理和资源管理(如确保数据库在不再需要时被正确关闭)。

这个示例展示了如何在Flutter应用中使用sqlcipher_library_windows来加密和解密SQLite数据库。希望这能帮助你开始使用SQLCipher来保护你的数据。

回到顶部