B4A Library xSQLCipher for Android Sqlcipher 4.5.4

This library is modified based on Erel's source code. I tried popular SQLCipher libraries like Zetetic, Guardianproject but Sqlcipher worked better, even though this library is no longer updated.
Some functions, because I don't have time, I haven't tested them yet. I posted the source code here. If there are any errors, please download the source code from Github.com

* Create new database on Android OS
sqlci.initializeCipher("dtest", "swqhccKWiaLKJuPCGH2ebA==", 20)

* Copy other source from Asset folder:| If your database is blank password, it can't not change

Dim target As String = File.Combine(File.DirInternalCache, "db_cipher.db")
File.Copy(File.DirAssets, "db_cipher.db",File.DirInternalCache, "db_cipher.db")
sqlci.initializeCopy("sqlci", target, "", 1)

* A tool help you create Sqlcipher on desktop: (console_sqlcipher_1.8.0.zip)
sqladmin.png



New method for xSQLCipher library:
ChangePassword(password As String)
ChangePassword(password() As Byte)
getDatabasePath As String
encrypt(RealPath As String, passphrase() As Byte)
decrypt(RealPath As String, passphrase() As Byte)
isDBEncrypted() as boolean
DeleteTable(table as string, where as string, arg as string)
PageSize() as long
DatabasePath() as string


GenerateAESKey and token
xEncrypter:
Dim tken As xEncrypter
Dim token As String = tken.encrypt(tken.generateAESKey, "12345678")    ' 128 bits (16 bytes)
Dim seckey() As Byte = tken.SecretKey
 
Log("HEX=" & tken.parseByte2HexStr(seckey))

You can save your publickey to Preferences
TokenManager:
Dim tokenManganer As TokenManager
tokenManganer.initialize
tokenManganer.saveTokenToPreferences("sql_pass", token)


xSQLCipher:
#AdditionalJar: sqlite-2.4.0.aar
#AdditionalJar: android-database-sqlcipher-4.5.4.aar

Dim sqlci As xSQLCipher
Dim key As String = "Hello world"
Dim c As B4XCipher
Dim b() As Byte = c.Encrypt(key.GetBytes("utf8"), "12345678")
sqlci.initializeCipher(sqlci, "db3.db", "12345678", 1)

Sub Button1_Click
    sqlci.ExecNonQuery("CREATE TABLE table1 (col1 TEXT, col2 INTEGER, col3 INTEGER)")
    For i=0 To 10
        sqlci.ExecNonQuery2("INSERT INTO table1 VALUES (?, ?, ?)", Array As Object("some text" & i, i, i * 2))
    Next
 
End Sub

Private Sub Button2_Click
    Dim Cursor As Cursor
    Cursor = sqlci.ExecQuery("SELECT col1, col2 FROM table1")
    For i = 0 To Cursor.RowCount - 1
        Cursor.Position = i
        Log(Cursor.GetString("col1"))
        Log(Cursor.GetInt("col2"))
    Next
End Sub
 

Attachments

  • Test.zip
    3.8 KB · Views: 54
  • android-database-sqlcipher-4.5.4.jar
    114.5 KB · Views: 34
  • sqlite-2.4.0.jar
    30.5 KB · Views: 33
  • Test.zip
    3.9 KB · Views: 35
  • Test3.zip
    5.1 KB · Views: 30
  • xSQLCipher.zip
    25.9 KB · Views: 41
Last edited:

RB Smissaert

Well-Known Member
Licensed User
Longtime User
This library is modified based on Erel's source code. I tried popular SQLCipher libraries like Zetetic, Guardianproject but Sqlcipher worked better, even though this library is no longer updated.
Some functions, because I don't have time, I haven't tested them yet. I posted the source code here. If there are any errors, please download the source code from Github.com

New method for xSQLCipher library:
ChangePassword(password As String)
ChangePassword(password() As Byte)
getDatabasePath As String
encrypt(RealPath As String, passphrase() As Byte)
decrypt(RealPath As String, passphrase() As Byte)


xSQLCipher:
#AdditionalJar: sqlite-2.4.0.aar
#AdditionalJar: android-database-sqlcipher-4.5.4.aar

Dim sqlci As xSQLCipher
Dim key As String = "Hello world"
Dim c As B4XCipher
Dim b() As Byte = c.Encrypt(key.GetBytes("utf8"), "12345678")     
sqlci.initializeCipher(sqlci, "db3.db", "12345678", 1)

Sub Button1_Click
    sqlci.ExecNonQuery("CREATE TABLE table1 (col1 TEXT, col2 INTEGER, col3 INTEGER)")
    For i=0 To 10
        sqlci.ExecNonQuery2("INSERT INTO table1 VALUES (?, ?, ?)", Array As Object("some text" & i, i, i * 2))
    Next
  
End Sub

Private Sub Button2_Click
    Dim Cursor As Cursor
    Cursor = sqlci.ExecQuery("SELECT col1, col2 FROM table1")
    For i = 0 To Cursor.RowCount - 1
        Cursor.Position = i
        Log(Cursor.GetString("col1"))
        Log(Cursor.GetInt("col2"))
    Next
End Sub
Isn't SQLCipher made by Zetetic?

RBS
 

Alexander Stolte

Expert
Licensed User
Longtime User
Isn't SQLCipher made by Zetetic?
This library is modified based on Erel's source code. I tried popular SQLCipher libraries like Zetetic, Guardianproject but Sqlcipher worked better, even though this library is no longer updated.
Some functions, because I don't have time, I haven't tested them yet. I posted the source code here. If there are any errors, please download the source code from Github.com
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
This just looked confusing to me:
>> I tried popular SQLCipher libraries like Zetetic, Guardianproject but Sqlcipher worked better

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
This library is modified based on Erel's source code. I tried popular SQLCipher libraries like Zetetic, Guardianproject but Sqlcipher worked better, even though this library is no longer updated.
Some functions, because I don't have time, I haven't tested them yet. I posted the source code here. If there are any errors, please download the source code from Github.com

New method for xSQLCipher library:
ChangePassword(password As String)
ChangePassword(password() As Byte)
getDatabasePath As String
encrypt(RealPath As String, passphrase() As Byte)
decrypt(RealPath As String, passphrase() As Byte)


xSQLCipher:
#AdditionalJar: sqlite-2.4.0.aar
#AdditionalJar: android-database-sqlcipher-4.5.4.aar

Dim sqlci As xSQLCipher
Dim key As String = "Hello world"
Dim c As B4XCipher
Dim b() As Byte = c.Encrypt(key.GetBytes("utf8"), "12345678")     
sqlci.initializeCipher(sqlci, "db3.db", "12345678", 1)

Sub Button1_Click
    sqlci.ExecNonQuery("CREATE TABLE table1 (col1 TEXT, col2 INTEGER, col3 INTEGER)")
    For i=0 To 10
        sqlci.ExecNonQuery2("INSERT INTO table1 VALUES (?, ?, ?)", Array As Object("some text" & i, i, i * 2))
    Next
  
End Sub

Private Sub Button2_Click
    Dim Cursor As Cursor
    Cursor = sqlci.ExecQuery("SELECT col1, col2 FROM table1")
    For i = 0 To Cursor.RowCount - 1
        Cursor.Position = i
        Log(Cursor.GetString("col1"))
        Log(Cursor.GetInt("col2"))
    Next
End Sub
Tried to compile but got error:
Could not find file 'C:\Program Files\Anywhere Software\B4A\libraries\sqlite-2.4.0.aar'.

Looked at your mentioned sources (Github.com), but couldn't find it.

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Ignore that, got that file now from the same site and got it compiling now.

RBS
Got this working fine now after fixing an error to do with running a different password method on an already existing DB:

B4X:
Sub Activity_Create(FirstTime As Boolean)
    
    Dim bDBDeleted As Boolean
    Dim bStringPassword As Boolean = False
    
    Activity.LoadLayout("Layout")
    
    Dim key As String = "Hello world"
    Dim c As B4XCipher
    
    'if you don't delete the DB that was created with a different password method (string or byte array)
    'then there will be an error:
    'android.database.sqlite.SQLiteException: file is not a database: , while compiling:
    'select count(*) from sqlite_master;
    '----------------------------------------------------------------------------------------------------
    bDBDeleted = File.Delete(File.DirInternal, "db3.db")
    Log("bDBDeleted: " & bDBDeleted)
    
    If bStringPassword Then
        sqlci.initializeCipher("SQL", File.DirInternal & "/db3.db", "12345678", 1)
    Else
        Dim b() As Byte = c.Encrypt(key.GetBytes("UTF8"), "12345678")
        sqlci.initializeCipher2("SQL", File.DirInternal & "/db3.db", b, 1)
    End If
    
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub Button1_Click
    
    'as the DB was deleted on app start we don't really need the: if not exists anymore
    sqlci.ExecNonQuery("CREATE TABLE if not exists table1 (col1 TEXT, col2 INTEGER, col3 INTEGER)")
    
    For i = 0 To 10
        sqlci.ExecNonQuery2("INSERT INTO table1 VALUES (?, ?, ?)", Array As Object("some text" & i, i, i * 2))
    Next
    
End Sub

Private Sub Button2_Click
    
    Dim RS As ResultSet
    
    RS = sqlci.ExecQuery("SELECT col1, col2 FROM table1")
    
    Do While RS.NextRow
        Log(RS.GetString2(0))
        Log(RS.GetInt2(1))
    Loop
    
    Log("------------------------------------------")
    
End Sub

It looks you used a different encryption method than in the code written by Zetetic.
What was the reason for that?

In your Github source code I noticed sqlcipher-android-4.5.6.aar, but it looks this is not used in your wrapper.
Is this so and if so what was the reason for that?

Thank in any case you this very interesting posting.

RBS
 

tummosoft

Member
Licensed User
Longtime User
Isn't SQLCipher made by Zetetic?

RBS
Isn't SQLCipher made by Zetetic?

RBS
net.sqlcipher.database is old project's Zetetic LLC (stop update at 2011), their current project has namespace net.zetetic. However, someone compile the android-database-sqlcipher-4.5.4.aar, only this version working. The official library not working, it can't load native library.
 

tummosoft

Member
Licensed User
Longtime User
Got this working fine now after fixing an error to do with running a different password method on an already existing DB:

B4X:
Sub Activity_Create(FirstTime As Boolean)
   
    Dim bDBDeleted As Boolean
    Dim bStringPassword As Boolean = False
   
    Activity.LoadLayout("Layout")
   
    Dim key As String = "Hello world"
    Dim c As B4XCipher
   
    'if you don't delete the DB that was created with a different password method (string or byte array)
    'then there will be an error:
    'android.database.sqlite.SQLiteException: file is not a database: , while compiling:
    'select count(*) from sqlite_master;
    '----------------------------------------------------------------------------------------------------
    bDBDeleted = File.Delete(File.DirInternal, "db3.db")
    Log("bDBDeleted: " & bDBDeleted)
   
    If bStringPassword Then
        sqlci.initializeCipher("SQL", File.DirInternal & "/db3.db", "12345678", 1)
    Else
        Dim b() As Byte = c.Encrypt(key.GetBytes("UTF8"), "12345678")
        sqlci.initializeCipher2("SQL", File.DirInternal & "/db3.db", b, 1)
    End If
   
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub Button1_Click
   
    'as the DB was deleted on app start we don't really need the: if not exists anymore
    sqlci.ExecNonQuery("CREATE TABLE if not exists table1 (col1 TEXT, col2 INTEGER, col3 INTEGER)")
   
    For i = 0 To 10
        sqlci.ExecNonQuery2("INSERT INTO table1 VALUES (?, ?, ?)", Array As Object("some text" & i, i, i * 2))
    Next
   
End Sub

Private Sub Button2_Click
   
    Dim RS As ResultSet
   
    RS = sqlci.ExecQuery("SELECT col1, col2 FROM table1")
   
    Do While RS.NextRow
        Log(RS.GetString2(0))
        Log(RS.GetInt2(1))
    Loop
   
    Log("------------------------------------------")
   
End Sub

It looks you used a different encryption method than in the code written by Zetetic.
What was the reason for that?

In your Github source code I noticed sqlcipher-android-4.5.6.aar, but it looks this is not used in your wrapper.
Is this so and if so what was the reason for that?

Thank in any case you this very interesting posting.

RBS

Because the code is not yet complete, I'm testing a few different encodings from other source code. So things are a bit messy.. and bug.
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
net.sqlcipher.database is old project's Zetetic LLC (stop update at 2011), their current project has namespace net.zetetic. However, someone compile the android-database-sqlcipher-4.5.4.aar, only this version working. The official library not working, it can't load native library.
> The official library not working, it can't load native library.

OK.
When you say official library do you mean the library that uses sqlcipher-android-4.5.6.aar?

RBS
 

tummosoft

Member
Licensed User
Longtime User
> The official library not working, it can't load native library.

OK.
When you say official library do you mean the library that uses sqlcipher-android-4.5.6.aar?

RBS

Yes, the library has namespace is net.zetetic.database.
Many users are experiencing issues with this library. Unfortunately, no readily available solution seems to exist. I've even attempted the author's recommended approach involving the relinker library, but the problem persists.
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Yes, the library has namespace is net.zetetic.database.
Many users are experiencing issues with this library. Unfortunately, no readily available solution seems to exist. I've even attempted the author's recommended approach involving the relinker library, but the problem persists.
OK, thanks for confirming that.

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Yes, the library has namespace is net.zetetic.database.
Many users are experiencing issues with this library. Unfortunately, no readily available solution seems to exist. I've even attempted the author's recommended approach involving the relinker library, but the problem persists.
I just tried your xSQLCipher in a large app with one large encrypted DB and one large unencrypted DB and a few smaller unencrypted DBs.
It seems that InitializeCipher creates a new DB, even if that DB already exists.
Do I need to user just the standard .Initialize?
What are the arguments to be provided to that?

RBS
 

tummosoft

Member
Licensed User
Longtime User
I just tried your xSQLCipher in a large app with one large encrypted DB and one large unencrypted DB and a few smaller unencrypted DBs.
It seems that InitializeCipher creates a new DB, even if that DB already exists.
Do I need to user just the standard .Initialize?
What are the arguments to be provided to that?

RBS

I fixed error and update new version!
 
Top