「这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战」。
Flutter持久化库drift(原moor)官方文档翻译汇总 - 掘金 (juejin.cn)
本文翻译自 drift 的 官方文档 Encryption (simonbinder.eu)。
肉翻多有不足,不吝赐教。
加密
在加密的数据库上使用 drift 。
有两种方式可以在加密的数据库上使用 drift 。encrypted_moor 包和 moor_flutter 类似,使用用 java 写的平台插件。作为选择,可以使用基于 ffi 实现的 sqlcipher_flutter_libs 包。
使用 encrypted_moor
从版本1.7开始,我们有一个版本的 drift , 可以通过使用 sqflite_sqlcipher 库(由@davidmartos96开发)的加密数据库。要使用这个版本的 drift ,需要从 pubspec.yaml 中移除 moor_flutter 的依赖,然后替换为下面的内容:
dependencies:
drift: ^1.0.1
encrypted_moor:
git:
url: https://github.com/simolus3/moor.git
path: extras/encryption
在 APP 中,不再导入 package:moor_flutter/moor_flutter (或 package:drift/native.dart ,应该导入 package:drift/drift.dart 和 package:encrypted_moor/encrypted_moor.dart 。
最后,把 FlutterQueryExecutor (或 NativeDatabase) 替换为 EncryptedExecutor 。
在 Android 和 iOS 上额外的安装
为了使SQLCipher 能够正常运转,需要在工程中做一些额外的步骤。 例如:在 Android 上配置ProGuard 用于发布。
阅读指南 (
用法和安装指南可以忽略,它们会在 moor 内部处理)
NativeDatabase 的 加密版
可以使用新的带加密执行器的 drift/native 库。这允许在多个平台上使用加密的 drift 数据库,特别是对于桌面应用。
安装
要使用 sqlcipher,需要添加 sqlcipher_flutter_libs 依赖:
dependencies:
sqlcipher_flutter_libs: ^0.5.0
如果已经添加了 sqlite3_flutter_libs 依赖,先删除这个依赖。
sqlite3_flutter_libs 和 sqlcipher_flutter_libs 并不兼容,因为它们各自提供了一个不同的 sqlite3 原生 api 的集合。
在 Anrdoid 上,需要改变 sqlite3 包的打开行为,使用加密的库替换常规的 libsqlite3.so:
import 'package:sqlite3/open.dart';
// 使用 drift 之前调用此方法
void setupSqlCipher() {
open.overrideFor(
OperatingSystem.android, () => DynamicLibrary.open('libsqlcipher.so'));
}
在后台数据库中使用 drift 时,也需要在后台 isolate 中调用 setupSqlCipher 。
在 iOS 和 MacOS 上,不需要其它额外的安装 - 只需要依赖 sqlcipher_flutter_libs。
在 Windows 和 Linux 上,当分发应用时,现在需要手动将 SQLCipher 的一个版本包含进去。更多信息参考这里。
代替包含 sqlite3.dll 或 libsqlite3.so,需要把各自版本的 SQLCipher 包含进去。
使用
SQLCipher 实现了 sqlite3 的 C 的 api ,这意味着可以不作任何修改,继续使用 sqlite3 包或 drift/ffi 。它们都和 sqlcipher_flutter_libs 完全兼容。
实际上要加密一个数据库,必须在使用前设置一个密钥。在 drift 文件中有个不错的设置密钥的地方,就是 NativeDatabase 的 setup 参数,在任何情况下这都会在 drift 使用数据库之前运行。
NativeDatabase(
File(...),
setup: (rawDb) {
rawDb.execute("PRAGMA key = 'passphrase';");
}
);
重要注意事项
在原生端, SQLCipher 和 sqlite3 相互冲突。如果应用的包同时依赖这两个本地库,实际上从中得到的一个可能在一些平台上变成未定义的。特别是,如果依赖 sqlcipher_flutter_libs 和另外的依赖 sqflite 的包,仍然会得到常规的不支持加密的 sqlite3 。
由于这个原因,建议在运行时检查 cipher_version 是否可用。
bool _debugCheckHasCipher(Database database) {
return database.select('PRAGMA cipher_version;').isNotEmpty;
}
接下来,在使用数据库之前添加一个 assert(_debugCheckHasCipher(database)) 。合适的地方是 NativeDatabase 的 setup 参数:
NativeDatabase(
File(...),
setup: (rawDb) {
assert(_debugCheckHasCipher());
rawDb.execute("PRAGMA key = 'passphrase';");
}
);
如果检查到加密版本不可用,可以看下这里的文档中有什么建议。