在iOS应用程序中由SQLCipher加密的数据库将永远无法访问

时间:2013-12-19 08:01:41

标签: ios objective-c sqlite concurrency sqlcipher

我最近修改了我的iOS应用程序,为使用SQLCipher加密的数据库和非加密数据库(也是SQLite)启用了序列化模式。我还为每个数据库维护一个静态sqlite3连接,每个数据库只打开一次(通过简单地检查空值)并在应用程序的整个生命周期内共享。

应用程序需要具有类似同步的行为,该行为将使用soap请求定期从远程数据库下载大量记录,并更新本地加密数据库的内容。当然,使用该应用程序的人可能会也可能不会更新或读取数据库,具体取决于他们正在做什么,所以我做了上段所述的更改。

在进行短期测试时,似乎没有任何关于工作方式的问题,而且我还遇到任何问题。

但是,有些用户报告他们已经失去了对加密数据库的访问权限,而我正试图找出原因。

我的想法如下:另一个开发人员编写的方法声明所有sqlite3_stmt都是静态的(我相信这段代码是在有问题的版本中)。在过去,我注意到当使用特定方法的两个线程同时运行时崩溃。一个线程在另一个线程正在使用它时完成,修改或替换sqlite3_stmt。崩溃并不总是发生,因为他已将大部分SQLite代码包装在try / catch块中。如果SQLite使用prepare和finalize来实现锁定,那么在这种情况下由于它们的静态特性而发生的sqlite3_stmt的孤立是否会使数据库进入不可操作的状态?例如,当一个语句在步进后获取一个独占锁被替换为在另一个线程中运行的同一方法中的赋值时?

我意识到这并不一定意味着数据库将永久无法使用,但请考虑这种情况:

在应用程序生命周期的某个时刻,它将重新加密加密数据库,并将该密钥存储在另一个数据库中。假设它成功重新加密了加密数据库,但由于我上面提到的内容,新密钥没有存储在其他数据库中。 如果数据库在某些时候没有被破坏(我实际上并没有指望这种情况),这是我能解释为什么用户可能无法使用加密数据库的唯一解释重新启动iOS应用程序,因为应用程序将是唯一访问数据库文件的应用程序。

由于我无法重现这个问题,我只能推测出推理可能是什么。你有什么想法?对于很少发生的事情,这看起来似乎是合情合理的吗?你还有其他想法可以研究吗?

1 个答案:

答案 0 :(得分:0)

如果数据库已重新加密,并且数据库的密钥未成功存储在其他数据库中,则肯定会导致问题。