【发布时间】:2013-05-09 07:46:10
【问题描述】:
我正在使用SQLCipher for Android 并试图确定测试用户提供的密码是否有效的正确方法。
我的第一个想法是尝试使用给定密码打开数据库,使用SQLiteOpenHelper.getReadableDatabase(password) 的 SQLCipher 实现,然后捕获弹出的SQLiteException。
这确实有效,但问题是因为 Android API 实际上封装了底层 C 调用,它为您做了很多工作 - 具体来说,当您使用 Android API 打开数据库时,它会打开数据库,运行原生 C 级 sqlite3_key 方法(使用提供的密码),然后尝试在数据库上设置区域设置,无论提供的密码是否正确。
此时Android库尝试设置locale,底层数据库抛出“加密还是不是数据库”SQLiteException,被捕获并重新抛出;但在此之前,一个不相关的错误被写入日志,本质上是说无法设置区域设置并且数据库正在关闭(包含堆栈跟踪)。因为这是由 Android 库专门编写的,所以我无法抑制它,在日志中留下一个丑陋的错误,这实际上与我原来的问题无关,只是我输入了错误的密码。
由于Android库不暴露C级调用,我不能只使用SQLCipher API文档中关于Testing the Key描述的方法,因为我没有权限直接打开数据库。
我倾向于使用SQLiteDatabaseHook,但据我所知,这排除了我使用SQLiteOpenHelper 的可能性,它似乎没有提供设置挂钩的方法。
还有其他人知道测试输入密码是否通过 SQLCipher Android API 正确解密 SQLCipher 数据库的更好方法吗?我完全希望调用一个方法并检查是否引发了异常 - 我不希望该操作尝试在数据库上执行无关处理(如设置区域设置)并将一个完全无法抑制的错误写入我的日志。
【问题讨论】:
-
"...这实际上与我原来的问题无关,只是我输入了错误的密码" -- 不,这是原来的问题:你输入了错误的密码,这这就是 set-locale 操作失败的原因。 “我不能只使用 SQLCipher API 文档中描述的关于测试密钥的方法......” - 您的结果将与您目前得到的结果相同,除了在 LogCat 中可能没有任何无关的痕迹。除此之外,您对“任何更好的方法”的标准是什么?
-
很抱歉,我显然没有说清楚。我要做的就是检查我是否输入了错误的密码。我完全同意我的结果是一样的(打电话,检查错误)。我对“任何更好的方法”的标准是没有多余的 setLocale 处理和错误。
-
我只是提出一个问题,让他们不记录错误并且不用担心它。除此之外,我推荐 sqlcipher Google Group 以获得更多帮助。
-
看起来您在这里问了基本相同的问题:github.com/sqlcipher/android-database-sqlcipher/issues/76,但也没有得到您满意的答案。