是否有正确的方法来测试用户提供的SQLCipher密码在Android上是否有效?

mWi*_*lis 7 android sqlcipher

我正在使用SQLCipher for Android,我正在尝试确定测试用户提供的密码是否有效的正确方法.

我的第一个倾向是尝试使用给定的密码打开数据库,使用SQLCipher实现SQLiteOpenHelper.getReadableDatabase(password),然后捕获SQLiteException弹出的数据库.

这确实有效,但问题是因为Android API实际上包含了底层的C调用,它为你做了很多工作 - 特别是当你使用Android API打开数据库时,它会打开数据库,运行本机C级sqlite3_key方法(使用提供的密码),然后尝试在数据库上设置区域设置,无论提供的密码是否正确.

此时,Android库尝试设置区域设置,底层数据库抛出"加密或不是数据库" SQLiteException,它被捕获并重新抛出; 但在此之前,会将无关的错误写入日志,实质上是说无法设置区域设置并且数据库正在关闭(包含堆栈跟踪).因为这是由Android库专门编写的,所以我无法抑制它,在日志中留下一个实际上与我原来的问题无关的丑陋错误,这只是我传入了错误的密码.

因为Android库不公开C级调用,所以我不能只使用SQLCipher API文档中描述的关于测试密钥的方法,因为我没有权限直接打开数据库.

我倾向于使用SQLiteDatabaseHook,但最好的我能说,这排除了我的使用SQLiteOpenHelper,这似乎没有提供设置钩子的方法.

有没有其他人知道更好的方法来测试输入密码是否通过SQLCipher Android API正确解密SQLCipher数据库?我完全希望调用一个方法并检查抛出的异常 - 我不想要的是操作尝试在数据库上执行无关的处理(如set locale)并在我的日志中写入一个完全不可抑制的错误.

小智 1

适用于 Android 的 SQLCipher 不知道您在调用后提供的密码无效,因为直到针对 后面的数据库发出 SQL 命令(例如您上面引用的方法sqlite3_key)之后才会使用数据库密钥。问题是,提供无效键可能只是执行第一个 SQL 语句时可能出现问题的其他可能情况之一。数据文件损坏、HMAC 检查失败或打开非数据库文件都可能导致出现相同的错误消息。有关详细说明,请查看此线程。最好在尝试打开数据库时捕获异常并在客户端应用程序中进行相应处理。sqlite3_keysetLocale(...)