Using SQLCipher on Android from C/C++ code

829 views
Skip to first unread message

Luca

unread,
May 8, 2012, 3:40:47 AM5/8/12
to sqlc...@googlegroups.com
Hi! I'm trying to use SQLCipher on Android by using the library directly from C/C++ code. I don't want to use the Java wrapper. With a database without key, everything seems to be working. I can create queries and get results. On iOS, the same code seems to work also with encrypted databases. The problem comes on Android when using a database with a key set.

I tried to set it this way:

stringstream stream;
stream << "pragma KEY=mykey;";
sqlite3_prepare_v2(db, stream.str().c_str(), -1, &statement, NULL);
sqlite3_step(statement);
sqlite3_finalize(statement);

The step function returns SQLITE_DONE. But queries then return "file is encrypted or is not a database". In SQLCipher sources I see the prepare function for UTF-16 is used, by passing the C-string coming from GetStringChars JNI function. Everything seems correct and again the step functions returns SQLITE_DONE. But then "file is encrypted or is not a database".

I also tried to use the sqlite3_key function passing the UTF8 string, but the same happens.

Anyone who noticed this or who has a clue of the reason for this? On iPhone simulator everything seems ok.

Luca

Stephen Lombardo

unread,
May 8, 2012, 9:47:20 AM5/8/12
to sqlc...@googlegroups.com
Luca,

Unfortunately there are a large number of potential issues here, and it's not possible to narrow it down from your description. Here is a short list of things that may help to narrow it down

1. Does the database you are trying to open already exist? If so, try creating a database from scratch to see if that works.
2. If so, what version of SQLCipher was used to create it? 
3. What version of SQLCipher for Android are you using to open it? Make sure it matches the version that created it.
4. Are you sure you have linked your JNI code against the sqlcipher library, and not the default sqlite implementation? 
5. Are you sure you have all of the requisite libraries present in your application lib folder?
6. Is the example below contrived, or the actual code? If so, you are missing quotes around 'mykey'; 
7. Try using sqlite3_exec instead of the prepare interface for the pragma.

Cheers,
Stephen

Luca

unread,
May 8, 2012, 1:11:12 PM5/8/12
to sqlc...@googlegroups.com
I should have specified better the situation maybe. Anyway thanks for your help!

  1. Yes, the database exists. I created it using SQLCipher reading a dump after specifying the key on a Linux machine. Seems to work fine there.
  2. I compiled for Linux with sources from the git.
  3. I downloaded the last version compiled for Android (didn't compile it myself). Same for iOS, taken from the git at the same time. How can I check the version of the lib and of the sources? I can only find the version if SQLite. Is it different from the version of SQLCipher?
  4. My Java class is loading explicitly the two libraries of SQLCipher, so I guess yes, it shouldn't load the system's SQLite.
  5. I have two libraries (stlport_shared and sqlcipher_android). Also, consider that everything is working correctly if no password is specified. If I don't load those libs, I get an UnsatisfiedLinkError exception for my C library.
  6. Yes sorry, that is the piece of code I'm testing, I commonly place the ' around, but I also tried without, escaped and not, just in case.
  7. I tried this way: sqlite3_exec(db, "pragma KEY='mykey';", NULL, NULL, NULL). The returned value is 0, but still the error message is always the same. Is there an sqlite3 executable somewhere to use in Android? If I take that file and I use it in Linux, setting to mykey let me query the database just fine.

On iOS the same code works correctly when the key is set like in the documentation [@"mykey" UTF8String]. Do you have any other suggestion? Thank you for your help!

Luca

Nick Parker

unread,
May 8, 2012, 4:24:08 PM5/8/12
to sqlc...@googlegroups.com, Luca
Hi Luca,

Depending on which version of the Android binaries you downloaded, this
could be the cause of the issue you are seeing. If you built sqlcipher
from a recent git clone you would be using the new database format which
included page level HMAC. The 1.1 version of the library available on
SQLCipher for Android is compiled against an older version of sqlcipher
and would cause an issue. A simple check to identify what binary
version you have; if the package name you import on Java is
info.guardianproject.* this is from the 1.1 library.

If this is the case, you can download the release candidate binaries [1]
which are built against the newer sqlcipher database format. You will
want to upgrade all of the files provided in the zip, including updating
you import statements. Could you give this a try and let us know your
results? Thanks!

1.
https://github.com/downloads/sqlcipher/android-database-sqlcipher/SQLCipher%20for%20Android%202.0.0-RC5.zip

On 5/8/12 12:11 PM, Luca wrote:
> I should have specified better the situation maybe. Anyway thanks for
> your help!
>
> 1. Yes, the database exists. I created it using SQLCipher reading a
> dump after specifying the key on a Linux machine. Seems to work fine
> there.
> 2. I compiled for Linux with sources from the git.
> 3. I downloaded the last version compiled for Android (didn't compile
> it myself). Same for iOS, taken from the git at the same time. How
> can I check the version of the lib and of the sources? I can only
> find the version if SQLite. Is it different from the version of
> SQLCipher?
> 4. My Java class is loading explicitly the two libraries of SQLCipher,
> so I guess yes, it shouldn't load the system's SQLite.
> 5. I have two libraries (stlport_shared and sqlcipher_android). Also,
> consider that everything is working correctly if no password is
> specified. If I don't load those libs, I get an UnsatisfiedLinkError
> exception for my C library.
> 6. Yes sorry, that is the piece of code I'm testing, I commonly place
> the ' around, but I also tried without, escaped and not, just in case.
> 7. I tried this way: sqlite3_exec(db, "pragma KEY='mykey';", NULL,
--
Nick Parker

Luca

unread,
May 8, 2012, 6:02:16 PM5/8/12
to sqlc...@googlegroups.com, Luca
Hi Nick,

at first sight, everything seems to be working with these new libraries. I tested both the sqlite3_exec and the sqlite3_key solution. I'll run more detailed tests but everything seems to work now also on Android.
Thank you very much for your help!

Luca
Reply all
Reply to author
Forward
0 new messages