Database cann't be decrypted after several times of use


#1

Hi,
Our iOS app uses sqlcipher to encrypt the database. In most cases, the database encryption and decryption are working properly. But there will be a rare exception. After the database is encrypted and used several times, the app may not decrypt the data properly.
The strange thing is that we copy the database from the app inside and can decrypt it with a SQLite tool called “DB Browser for SQLite”.
What are the possible reasons?


#2

Hello @Jusitin. Unfortunately this isn’t really enough information to comment or troubleshoot. Can you provide some relevant details about this problem? For example, what sqlcipher platform are you using (e.g. iOS, android, windows)? Are you getting an error message or code during database use, and if so what? What does your code look like? What query or statement is executing at the point that you get a failure?


#3

Hello, sjlombardo.

  1. We use iOS sqlcipher platform.
  2. The error message is “file is encrypted or is not a database”.
  3. Detailed code in the attachment:
    code.text.zip (1.9 KB)

#4

Hello @Jusitin - it looks like the code you provided has multiple paths, some opening the database unencrypted, others encrypted, and others rekeying a database. It doesn’t provide any context on where the key material is coming from, or what calls are failing. At this point it would probably be best if you could isolate a very simple, standalone application or class that reproduces the problem you are seeing. Then we can look into it further.


#5

Hello, sjlombardo. I’m sorry to reply to you so late. The attachment is a very simple class, but the problem is occasional.Class.zip (5.1 KB)


#6

Hello @Jusitin - On line 37 of FMEncryptHelper.m your code fails to close the database handle if it was unable to open the database with the new key. It then goes on to overwrite the database handle which has not been properly closed. It is certainly possible that could lead to undefined behavior.

Also, on lines 115, 148, and 154 you are passing key material as a part of a SQL statement via sqlite3_exec without proper parameter binding. You do not show where the key material comes from (the definitions of oldKey and newKey are stubbed out), but if the material is randomly generated or user provided it is certainly possible that it could contain characters that would not be parsed as intended. For the PRAGMA key calls, its worth noting you could use sqlite3_key and sqlite3_rekey instead of the PRAGMAs for simplicity.

It’s not possible to say conclusively whether these problems are responsible for the problem you are seeing, but they are both potential issues. I’d suggest fixing those and then seeing if the problems continue.

If you are still experiencing issues even with those fixes in place we would need to have a reproducible test case to analyze the issue further.


#7

Hello @sjlombardo - Thanks very much! I will fix those problems and then continue to observe.