Flutter数据库加密插件sqlcipher_flutter_libs的使用
Flutter数据库加密插件sqlcipher_flutter_libs的使用
Flutter 应用依赖此包后,将在 Android、iOS、macOS、Linux 和 Windows 平台上包含原生的 SQLCipher
库。由于 SQLCipher
与常规的 sqlite3
库具有兼容的 ABI,因此可以与未修改的 sqlite3
包一起使用。
使用此包
根据您的平台,可能需要进行一些设置工作和预防措施。特别是,请注意 iOS 和 macOS 上的兼容性问题!此外,在 Android 上也需要一个特殊的代码片段。
除了这些之外,这个包可以很好地与常规的 sqlite3
包一起使用。要打开一个加密的数据库,使用 sqlite3
包并运行一个 pragma 来解密它:
示例代码
import 'package:sqlcipher_flutter_libs/sqlcipher_flutter_libs.dart';
import 'package:sqlite3/open.dart';
import 'package:sqlite3/sqlite3.dart';
void main() {
// 如果是Android平台,重写默认的sqlite3打开方法为SQLCipher打开方法
open.overrideFor(OperatingSystem.android, openCipherOnAndroid);
// 打开数据库文件
final db = sqlite3.open('path/to/your/database/file');
// 检查是否成功使用了SQLCipher库
if (db.select('PRAGMA cipher_version;').isEmpty) {
throw StateError('SQLCipher library is not available, please check your dependencies!');
}
// 设置数据库的加密密钥
db.execute("PRAGMA key = 'your passphrase';");
// 从现在开始,您可以像使用任何其他 sqlite3 数据库一样使用这个加密数据库。
}
编译注意事项
根据目标平台的不同,可能需要额外的依赖项:
- Android: 使用预编译库,无需额外设置。
- macOS 和 iOS: 依赖于 SQLCipher pod。重要提示: 如果依赖于其他链接常规 sqlite3 库的包,可能会导致问题。请确保阅读重要建议。
- Linux: SQLCipher 链接了一个静态 OpenSSL 库(例如在 Debian 上使用
apt install libssl-dev
)。OpenSSL 链接到生成的.so
文件中,因此用户不需要安装 OpenSSL。 - Windows: SQLCipher 链接了一个静态 OpenSSL 库(使用 Chocolatey 的
choco install openssl
)。OpenSSL 静态链接到生成的.dll
文件中,因此用户不需要安装 OpenSSL。
在 Android 上使用此包时,您需要告诉 sqlite3
包如何打开 sqlcipher
,因为它将尝试默认打开常规的 sqlite3
二进制文件:
import 'package:sqlcipher_flutter_libs/sqlcipher_flutter_libs.dart';
import 'package:sqlite3/open.dart';
// 在使用任何 sqlite3 API 之前执行此操作
open.overrideFor(
OperatingSystem.android, openCipherOnAndroid);
当使用 drift
或 sqflite_common_ffi
等包装 sqlite3
包的包时,也需要这样做!对于其他平台,不需要 Dart 代码更改。如果在后台 isolate 中使用 package:sqlite3
(即使通过 package:drift
间接使用),也应在该 isolate 中调用 overrideFor
。
更多关于如何在 Flutter 应用中实际使用此包的详细信息,请参阅 sqlite3。
iOS 和 macOS 上的 sqlite3
不兼容问题
对于 iOS 和 macOS 构建,依赖此包将安装 SQLCipher
pod。当依赖于另一个链接常规 sqlite3
pod 或库的包时,这可能导致未定义行为,这意味着 SQLCipher 可能在您的应用中不可用。例如,google_mobile_ads
或 firebase_messaging
包可能会导致此问题。
要解决此问题,可以在 XCode 项目设置中的 “Other Linker Flags” 添加 -framework SQLCipher
。有关更多详细信息,请参阅:
为了尽早捕获这些错误,建议在打开数据库后选择 PRAGMA cipher_version
,并在返回空字符串时抛出异常,因为在这种情况下您没有使用 SQLCipher。
不同平台上的不同行为
在 Android、iOS 和 macOS 上,此包依赖 Zetetic(SQLCipher 的作者)管理的依赖项来在应用程序中包含 SQLCipher。由于 Windows 和 Linux 没有这样的解决方案,因此使用自定义构建脚本。此构建脚本灵感来自 sqlite3_flutter_libs
中使用的脚本,并禁用了 双引号字符串 功能。官方 SQLCipher 构建不这样做。
为了避免应用程序依赖于 SQL 中的双引号字符串,如果您针对这些平台,请在发布前在 Linux 或 Windows 上测试您的应用程序。
在 Android、iOS、macOS 和 Windows 上,SQLCipher 使用操作系统自带的原生加密库。在 Linux 上,默认情况下会包含静态链接的 OpenSSL。如果您更喜欢静态链接 OpenSSL,请在 linux/CMakeLists.txt
中添加:
set(OPENSSL_USE_STATIC_LIBS OFF)
Android 6 上的问题
在 Android 6 上加载原生库时似乎存在一个问题(参见 此问题)。如果您遇到这些崩溃,可以尝试在 gradle.properties
文件中设置 android.bundle.enableUncompressedNativeLibs=false
。请注意,这会增加应用程序安装后的大小。
或者,您可以使用此库中的 applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
方法。它将尝试在 Java 中打开 sqlcipher
,这似乎更可靠。在 Java 加载了原生库之后,我们也可以在 Dart 中打开它。该方法应在使用 sqlite3
(直接或通过 package:drift
的 NativeDatabase
间接使用)之前调用。
由于 applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
使用平台通道,因此在后台 isolate 中使用时可能会出现问题。我们建议在主 isolate 中等待它,在 启动可能使用数据库的后台 isolate 之前。
import 'package:sqlcipher_flutter_libs/sqlcipher_flutter_libs.dart';
void main() async {
await applyWorkaroundToOpenSqlCipherOnOldAndroidVersions();
// 其他初始化代码...
}
希望以上内容对您有所帮助!如果您有任何问题或需要进一步的帮助,请随时提问。
更多关于Flutter数据库加密插件sqlcipher_flutter_libs的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据库加密插件sqlcipher_flutter_libs的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 sqlcipher_flutter_libs
插件在 Flutter 中对 SQLite 数据库进行加密和解密的代码示例。这个插件基于 SQLCipher,一个流行的开源 SQLite 扩展,用于加密数据库。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 sqlcipher_flutter_libs
依赖:
dependencies:
flutter:
sdk: flutter
sqlcipher_flutter_libs: ^x.y.z # 请使用最新版本号替换 x.y.z
2. 导入插件并初始化
在你的 Dart 文件中导入 sqlcipher_flutter_libs
插件,并初始化数据库。以下是一个基本的示例:
import 'package:flutter/material.dart';
import 'package:sqlcipher_flutter_libs/sqlcipher_flutter_libs.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('SQLCipher Flutter Demo'),
),
body: Center(
child: DatabaseDemo(),
),
),
);
}
}
class DatabaseDemo extends StatefulWidget {
@override
_DatabaseDemoState createState() => _DatabaseDemoState();
}
class _DatabaseDemoState extends State<DatabaseDemo> {
late Database _db;
@override
void initState() {
super.initState();
initDatabase();
}
Future<void> initDatabase() async {
// 打开或创建一个加密数据库
String dbPath = await getDatabasesPath();
String encryptedDbPath = '$dbPath/encrypted.db';
// 设置密钥
String key = 'mysecretkey';
// 打开数据库
_db = await openDatabase(
encryptedDbPath,
key: key,
version: 1,
onCreate: (Database db, int version) async {
await db.execute('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');
},
onConfigure: (Database db) async {
await db.execute('PRAGMA cipher_version');
},
);
}
Future<void> insertData() async {
await _db.insert('test', {'name': 'Alice'});
await _db.insert('test', {'name': 'Bob'});
}
Future<List<Map<String, dynamic>>> queryData() async {
return await _db.query('test');
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () async {
await insertData();
setState(() {});
},
child: Text('Insert Data'),
),
ElevatedButton(
onPressed: () async {
List<Map<String, dynamic>> result = await queryData();
print(result); // 打印查询结果
},
child: Text('Query Data'),
),
],
);
}
}
3. 注意事项
- 密钥管理:密钥的存储和管理非常重要,请确保不要硬编码在代码中,使用安全的密钥管理服务。
- 性能:加密和解密操作会引入额外的性能开销,请根据实际需求评估性能影响。
- 平台支持:确保插件在你使用的平台上已经过充分测试,并遵循其文档和最佳实践。
这个示例展示了如何使用 sqlcipher_flutter_libs
插件创建一个加密的 SQLite 数据库,并进行基本的数据插入和查询操作。根据你的实际需求,你可以进一步扩展和优化代码。