Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RLM_ERR_INVALID_DATABASE] Realm cannot be decrypted after a migration from java-sdk to kotlin-sdk #1705

Closed
brnmr opened this issue Mar 20, 2024 · 4 comments · May be fixed by #1636
Closed

Comments

@brnmr
Copy link

brnmr commented Mar 20, 2024

How frequently does the bug occur?

Always

Description

We've recently decided to migrate from java-sdk to to the kotlin-sdk and when the app is first started right after the migration, the encrypted realm file cannot be opened with the same key that has been used to encrypt the realm prior to the migration to the kotlin-sdk. The error we're getting is as follows:

[RLM_ERR_INVALID_DATABASE]: Failed to open Realm file at path '/data/user/0/com.example.app/files/default.realm': Realm file decryption failed (Decryption failed: 'unable to decrypt after 0 seconds (retry_count=4, from=i != bytes_read, size=4096)')

Here are details about the SDK versions:

// Java-sdk version prior to migration
implementation("io.realm:realm-gradle-plugin:10.11.1")
// Kotlin-sdk version after the migration
implementation ("io.realm.kotlin:library-base:1.11.0")

We've verified that the key used for the realm config is the same before and after the migration so there should be no issue with the key itself. In addition, we did tests with unencrypted realm and in this case we don't have issues with the migration.

In addition, we tried to open the realm file using Realm Studio by providing the encryption key. We get warning that the realm file is in an outdated format which I'm not sure is related to the issue but after choosing the Backup and upgrade option, we are able to decrypt the realm database and see the content - everything is in there.

Screenshot 2024-03-20 at 17 24 57

Here is the code for generating the realm config:

private fun initRealmConfig(): RealmConfiguration? {
        // Increment whenever you made changes to the Realm* database models
        val schemaVersion: Long = 2
        
        // Get encryption key
        val realmKey = DBHelper.loadEncryptionKey(App.applicationContext())

        realmKey?.let {
            val realmConfig = RealmConfiguration.Builder(getSchemaClasses())
                .schemaVersion(schemaVersion)
                .migration(DBMigrationHelper.migrate())
                .encryptionKey(it)
                .build()

            // Once we've used the key to generate a config, erase it in memory manually
            Arrays.fill(realmKey, 0.toByte())

            return realmConfig
        }

        return null
    }

Stacktrace & log output

[RLM_ERR_INVALID_DATABASE]: Failed to open Realm file at path '/data/user/0/com.example.app/files/default.realm': Realm file decryption failed (Decryption failed: 'unable to decrypt after 0 seconds (retry_count=4, from=i != bytes_read, size=4096)')

Can you reproduce the bug?

Always

Reproduction Steps

  1. Run app version with java-sdk
  2. Migrate to kotlin-sdk
  3. Update the installed app version in step 1 with the migrated version

Problem

  • Realm decryption fails

Version

1.11.0

What Atlas App Services are you using?

Local Database only

Are you using encryption?

Yes

Platform OS and version(s)

Android

Build environment

Android Studio version: Hedgehog | 2023.1.1 Patch 2
Android Build Tools version: com.android.tools.build:gradle:7.2.2
Gradle version: gradle-7.4-bin

Copy link

sync-by-unito bot commented Mar 20, 2024

➤ PM Bot commented:

Jira ticket: RKOTLIN-1047

@brnmr
Copy link
Author

brnmr commented Mar 21, 2024

Hi guys,

After further debugging I figured out that this line in the initialization of the RealmConfigration is causing the issue. I still have no clue why since this was working fine in the java-sdk and was taken from the official documentation here: https://www.mongodb.com/docs/realm/sdk/java/realm-files/encryption/

This is the line I am referring to:

// Once we've used the key to generate a config, erase it in memory manually
Arrays.fill(realmKey, 0.toByte())

So, when I delete this line and update to the app version with the migrated java-sdk to kotlin-sdk, the database is working fine and can be decrypted without issues.

Any ideas?

@brnmr brnmr changed the title Realm cannot be decrypted after a migration from java-sdk to kotlin-sdk [RLM_ERR_INVALID_DATABASE] Realm cannot be decrypted after a migration from java-sdk to kotlin-sdk Mar 21, 2024
@rorbech
Copy link
Contributor

rorbech commented Apr 9, 2024

Hi @brnmr. The encryption key is actual not copied as part in the Kotlin RealmConfiguration, so clearing the data inbetween creating the configuration and opening the realm will cause the Realm.open to use the cleared key. The key is also used to asynchronously open some internal background instances of the realm which causes it to be a bit tricky when the memory can be cleared, as the asynchronous operations are not guaranteed to happen before Realm.open returns. The only safe way to know this at the moment is to wait for initialization of the internal realms by forcing an update through an empty transaction with:

realm.write {  }
realm.asFlow().filterIsInstance<UpdatedRealm<*>>().first()

We are working on a fix to this with a callback to provide the key and a callback when it is safe to clear the key again. This should ensure that the key is in memory as little as possible. The progress of that can be track in #1636

@brnmr
Copy link
Author

brnmr commented Apr 10, 2024

Thank you @rorbech for the provided information. We are looking forward to the callback for when it's safe to clear the key.

@brnmr brnmr closed this as completed Apr 10, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants