Android Tutorial Android database encryption with SQLCipher library

Status
Not open for further replies.
SQLCipher is an open source project that extends SQLite and adds full database encryption.
License: https://www.zetetic.net/sqlcipher/open-source/

B4A SQLCipher is a special subtype of SQL object. There is almost no need to change any code in order to switch from regular SQL to SQLCipher.

The only difference between SQL API and SQLCipher API is the Initialize method.
SQLCipher.Initialize expects two additional values: Password and a second parameter that is not used (it was used in the past).

Password is the database password. You can pass an empty string if there is no password. Note that it is not possible to change the password (or set a new password) to an existing database.

Code changes required to convert from SQL to SQLCipher
- Declare the SQL object as SQLCipher.
- Change the initialize code to:
B4X:
SQL1.Initialize(File.DirRootExternal, "1.db", True, DB_PASSWORD, "")

V1.70
V1.60
V1.50
  • Based on SQLCipher v3.59
  • Supports targetSdkVersion 26.
  • The icu.zip file is no longer required. You can delete it from the Files folder.
  • It is no longer required to disable the debugger virtual assets feature.
    Remove this line: #DebuggerForceStandardAssets: True
  • Old version: www.b4x.com/android/files/SQLCipher150.zip

Depends on: https://repo1.maven.org/maven2/net/...er/4.5.4/android-database-sqlcipher-4.5.4.aar
You should download and copy it to the additional libraries folder.
 

Attachments

  • SQLCipher.zip
    37.2 KB · Views: 388
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Last edited:

Andy S.

Member
Licensed User
Longtime User
I am using SQLCIpher v3. Everything worked fine using SQL. It seems when I do successive updates fired from EditExt.TextChanged events inside a transaction it crashes.

Andy
 

wonder

Expert
Licensed User
Longtime User
So, if I understood correctly, to add encryption to my SQLite B4A project (currently using DBUtils), all I need to do is change the initialization method into this:
B4X:
ProgressDialogShow("Initializing database...")
SQL1.Initialize(File.DirRootExternal, "1.db", True, DB_PASSWORD, "")
ProgressDialogHide
...and follow the remaining instructions.

Right?
Do I still need to include the standard SQL lib?
 

tucano2000

Active Member
Licensed User
Longtime User
V1.30 is released - It is based on SQLCipher v3.3.1. Previous versions are not compatible with Android 6.

Finally after much research and work I managed to solve this problem of incompatibility of the libraries of the V3 version V2 version

That's right, I'm saying it's possible to have any Android version, including 6.0, it can make the libraries of the new version V3 read and write older database of V2 version.

It's simple.

Once you initialize the database add the following line of code:

B4X:
SQLX.Initialize (File.DirInternal, "filename.xxx" False, databasepassword, "")
CursorX = SQLX.ExecQuery ("PRAGMA cipher_migrate") '<==== only enter this line

'continue here your code

To avoid delays, it is recommended to avoid open and close the database frequently.

Erel, if you can put that information in the first post of this topic.

I hope you enjoyed the information, and if possible a like me, it gave a lot of work and avoided me having to convert all my original database.
 
Last edited:

JTmartins

Active Member
Licensed User
Longtime User
I'm having a problem with this lib when in use with another lib I've created using the Native Library Generator Tool..

If I remove the lib that I've built with the tool, than SQL cypher runs OK...However, the c++ library I've mad, is actualy the one that generates the password for the SQLcypher Database as I do not trust to make it in B4A or JAVA as they can be decompiled much more easily that C++.

Any Ideas so that I can solve this situation ?

Many Thanks.

I get the following error when I use both libs.

I noticed that I get SQL.Initialize(File.DirRootExternal & "/Gesdriv in the error log...wich is not the complete path. Not sure if it has something to do with that.

** Activity (main) Create, isFirst = true **
main_activity_create (B4A line: 136)
SQL.Initialize(File.DirRootExternal & "/Gesdriv
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/GesdriverGPS.Gescola.pt-2/base.apk"],nativeLibraryDirectories=[/data/app/GesdriverGPS.Gescola.pt-2/lib/arm, /vendor/lib, /system/lib]]] couldn't find "libstlport_shared.so"
at java.lang.Runtime.loadLibrary(Runtime.java:366)
at java.lang.System.loadLibrary(System.java:988)
at net.sqlcipher.database.SQLiteDatabase.loadLibs(SQLiteDatabase.java:173)
at net.sqlcipher.database.SQLiteDatabase.loadLibs(SQLiteDatabase.java:169)
at anyhwheresoftware.b4a.objects.sqlcipher.SQLCipher.Initialize(SQLCipher.java:50)
at GesdriverGPS.Gescola.pt.main._activity_create(main.java:528)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
at GesdriverGPS.Gescola.pt.main.afterFirstLayout(main.java:102)
at GesdriverGPS.Gescola.pt.main.access$000(main.java:17)
at GesdriverGPS.Gescola.pt.main$WaitForLayout.run(main.java:80)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5637)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
 

JTmartins

Active Member
Licensed User
Longtime User
Well Erel,

When I unzip :

1 - With my Lib and SQLCipher I have the following folder structure under lib

arm64-v8a
armeabi
armeabi-v7a
mips
mips64
x86
x86-64

under armeabi I have the following files
libcryPT.so - my lib
libdatabase_sqlcipher.so
libsqlcipher_android.so
libstlport_shared.so

in all the other folders there is only the
libcryPT.so

2 - Only with SQLCipher on the project I have the following folder structure under lib

armeabi

under armeabi I have the following files

libdatabase_sqlcipher.so
libsqlcipher_android.so
libstlport_shared.so

So I presume this is where the problem resides. Should I keep the armeabi folder and delete all the others in option 1 ?

many thanks
 

JTmartins

Active Member
Licensed User
Longtime User
Instead of deleting inside the APK, I've actually deleted all folders inside the jar produced by the NLG except the armeabi, recompiled and it seems to be working fine now.

Many thanks.
 

jatko

Member
Licensed User
Longtime User
There is SqlCipher library v 3.3.0. Is there any newer? I have a problem with this library on Android 5.1.1. Lower version is fine (Android version).
 

jatko

Member
Licensed User
Longtime User
This is the latest version. Which error did you get?

It's very hard to describe it, because there is no special information during debuging.

There is only :
Ignoring event as service was destroyed: udp_packetarrived

I decided to use SQLcipher in my program. I changed:
before - Dim SQL As SQL
now - Dim SQL As SQLCipher
before - SQL.Initialize(File.DirInternal, "ph.sqlite", True)
now - SQL.Initialize(File.DirInternal, "ph_sh.sqlite", True, "password", "")

It works on 200 devices (Lenovo TAB 2 A7-30H - android 5.0.1; Samsung Galaxy TAB 2 - Android 4.1.2) and the only one Samsung Galaxy TAB 4 - Android 5.1.1 it daesn't work. Program stop in the very beginning.
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Ignoring event as service was destroyed: udp_packetarrived
This is not related.

Samsung Galaxy TAB 4 - Android 5.1.1 it daesn't work. Program stop in the very beginning.
Maybe it is not an ARM device. There should be an error message in the logs. You might need to switch to USB debug mode to see it.
 

jatko

Member
Licensed User
Longtime User
That was the device problem. After "Factory data reset" it works.

Thank You Erel.
 

marcoperoni

Member
Licensed User
Longtime User
SQLite db created outside of the application?

This is great news, however I do have a question:

How would I encrypt/set a password for a SQLite database that has been created/populated outside of a B4A application which is then to be used in the application?

Good news: with the latest version of the open source DB Browser for SQLite ( http://sqlitebrowser.org/ ) you can Encrypt an existent SQLite DB with SQLCipher . I Crypted with sqlitebrowser and then opened with SQLCypher library without problems.
 
Status
Not open for further replies.
Top