· 2 min read Posted by Kevin Galligan

SQLCipher and Kotlin Multiplatform Mobile

How we implemented Kotlin Multiplatform Mobile encryption with SQDelight and SQLCipher for Kotlin 1.4.0 and made the iOS side work

Here’s a quick little followup to Sam’s post: Multiplatform Encryption with SQLDelight and SQLCipher. Recently for a client we needed to implement this with Kotlin 1.4.0, and ran into a couple issues. I’m only going to describe how to get the iOS side working as Android is pretty straightforward (although Android is in the sample and video).

Here’s KaMPKit updated to use SQLCipher

The cipher key is hardcoded in code. Do *not* do that in your app. You need to get your key from a more secure source.

Here’s a video showing edits on KaMP Kit:

SQLiter ran into an issue setting the key for SQLCipher. That apparently used to work, but stopped at some point. There was a PR to fix that, but that was not merged in before 0.7.0 was released. 0.7.0 is used in the current version of SQLDelight, so you’ll need to force this fixed version.

sourceSets["iosMain"].dependencies {
    implementation("co.touchlab:sqliter:0.7.1") {
        version {
            strictly("0.7.1")
        }
    }
    //etc...
}

We also had an issue with our custom cocoapods fork, so if by chance you’re using that, you’ll need to use the latest, which is version 0.12.

To configure your SQLDelight driver for native, you need to supply a custom DatabaseConfiguration for SQLiter.

val schema = YourDb.Schema //SQLDelight Schema
val configuration = DatabaseConfiguration(
    name = "YourDbName",
    version = schema.version,
    create = { connection ->
        wrapConnection(connection) { schema.create(it) }
    },
    upgrade = { connection, oldVersion, newVersion ->
        wrapConnection(connection) { schema.migrate(it, oldVersion, newVersion ) }
    }
    ,key = yourCipherKey
)
val driver = NativeSqliteDriver(configuration)

To get this all to work in iOS, as discussed in Sam’s post, disable sqlite linking:

sqldelight {
    database("YourDb") {
        packageName = "co.touchlab.yourapp.db"
        linkSqlite = false
    }
}

Then add the SQLCipher dependency (if using cocoapods)

cocoapods[ext] {
    summary = "Shared code for YourApp"
    homepage = "https://github.com/touchlab"
    pod("SQLCipher", "~> 4.0")
}

Remember, if you add pod to your Gradle config, you need to build from Xcode and not the Gradle command line. I always forget this.

That should be it. If there are other missing details, let me know and I’ll update.