SQLite Android 绑定

文档
登录

使用 SQLite 加密扩展

SQLite 加密扩展 提供了一种简单的方法来创建、读取和写入加密的数据库文件。它可以与 SQLite Android 绑定一起使用,为任何应用程序添加加密数据库功能。

1. 构建启用 SEE 的版本

除非您使用 预构建的 aar 文件 来将 SEE 扩展与 SQLite Android 绑定一起使用,否则您需要构建一个自定义版本,无论是作为 自定义 aar 文件 还是通过 直接集成 代码到应用程序中。

为此,请按照上面链接的说明进行操作。但是,在运行ndk-build命令构建原生库之前

  1. 用启用了 SEE 的版本替换sqlite3.csqlite3.h文件(即 sqlite3.c 和 see.c 的连接 - 有关详细信息,请参阅上面的链接)。
  2. 编辑 Android.mk 文件,以便取消注释下面复制的两行中的第二行
      # If using SEE, uncomment the following:
      # LOCAL_CFLAGS += -DSQLITE_HAS_CODEC
    

2. 应用程序代码说明

2.1. 打开加密数据库

打开现有的加密数据库或创建一个新数据库的最佳方法是将加密密钥指定为 SQLite URI 数据库标识符 的一部分。例如,而不是“DatabaseName.db”,其中之一

  file:DatabaseName.db?key=secret
  file:DatabaseName.db?hexkey=0123ABCD

上面的第一种形式,指定文本密钥,需要 SQLite 版本 3.19.0。

或者,在打开或创建加密数据库后,应用程序可以立即执行 PRAGMA 以配置加密密钥。这必须在调用任何其他数据库方法之前完成。例如

  import org.sqlite.database.sqlite.SQLiteDatabase;

    ...

  SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("my.db", null);
  db.execSQL("PRAGMA key = 'secretkey'");

或者,如果您使用的是 SQLiteOpenHelper 辅助类,则 PRAGMA 必须是在 onConfigure() 回调函数中执行的第一件事。例如

  import org.sqlite.database.sqlite.SQLiteDatabase;
  import org.sqlite.database.sqlite.SQLiteHelper;

    ...

  class MyHelper extends SQLiteOpenHelper {
    ...
    void onConfigure(SQLiteDatabase db){
      db.execSQL("PRAGMA key = 'secretkey'");
    }
    ...
  }

请注意,使用 PRAGMA 指定如上所述的加密密钥与 WAL 模式不兼容。在 Android 中,启用 WAL 模式也会在后台启用连接池。这会提高多线程应用程序的并发性,但也使使用 PRAGMA 直接使用 SQLite 配置加密密钥变得不安全(因为 Android 可能会在任何时候创建和使用尚未配置的新 SQLite 连接)。

有关加密密钥的更多详细信息,请参阅 SEE 文档

2.2. 加密现有数据库或更改加密密钥

可以使用“PRAGMA rekey”或“PRAGMA rehexkey”命令加密未加密的数据库或更改现有数据库的加密密钥,如 SEE 文档 中“使用“key”PRAGMA”部分所述。

如果使用 WAL 模式,则会遇到与“PRAGMA key”相同的问题 - 在(重新)加密数据库后,它仅修改连接池中一个连接内部使用的密钥。这意味着当 Android 尝试使用不同的连接访问数据库时,它会抛出“文件已加密或不是数据库”异常 (SQLITE_NOTADB)。因此,需要修改 WAL 模式数据库的加密密钥的应用程序应该在运行“PRAGMA rekey”后立即创建一个新的 SQLiteDatabase(或 SQLiteOpenHelper)对象来访问数据库,并将新密钥指定为新 URI 标识符的一部分。

2.3. 与非 SEE 版本的其他区别

除了支持加密数据库外,启用 SEE 的版本在另外两个方面表现出不同的行为

  1. 在 Android 中,如果遇到数据库损坏,或者尝试打开不是 SQLite 数据库的文件,则默认行为是删除该文件并在其位置创建一个空的数据库文件。在启用 SEE 的版本中,默认行为是抛出异常。

    这样做的原因是提供错误的加密密钥与打开不是数据库文件的区别不大。在这种情况下,简单地删除文件似乎太危险了。

    可以使用 DatabaseErrorHandler 接口覆盖默认行为。

  2. 此模块的早期版本完全禁用了启用 SEE 的版本的 WAL 模式连接池。这 在此处更改 作为 3.19.0 开发周期的一部分。