Docs Menu

Docs HomeDevelop ApplicationsAtlas Device SDKs

Encrypt a Realm - Kotlin SDK

On this page

  • Encrypt a Local Realm
  • Encrypt a Synced Realm
  • Encryption and Atlas Device Sync
  • Encrypt App Metadata
  • Store & Reuse Keys
  • Performance Impact
  • Access Encrypted Realms from Multiple Processes

You can encrypt your realms to ensure that the data stored to disk can't be read outside of your application. You encrypt the realm file on disk with AES-256 + SHA-2 by supplying a 64-byte encryption key when first opening the realm.

Realm transparently encrypts and decrypts data with standard AES-256 encryption using the first 256 bits of the given 512-bit encryption key. Realm uses the other 256 bits of the 512-bit encryption key to validate integrity using a hash-based message authentication code (HMAC).

Warning

Do not use cryptographically-weak hashes for realm encryption keys. For optimal security, we recommend generating random rather than derived encryption keys.

Note

Encrypt a Realm on Open or Copy Unencrypted Realm

You must encrypt a realm the first time you open it. If you try to open an existing unencrypted realm using a configuration that contains an encryption key, Realm throws an error.

Alternatively, you can copy the unencrypted realm data to a new encrypted realm using the Realm.writeCopyTo() method. Refer to Copy Data into a New Realm for more information.

To encrypt a local realm, pass your encryption key to the encryptionKey property in the RealmConfiguration.Builder() used to open the realm.

The following code demonstrates how to generate an encryption key and open an encrypted local realm:

// return a random key from the given seed
fun getRandomKey(seed: Long? = null): ByteArray {
// generate a new 64-byte encryption key
val key = ByteArray(64)
if (seed != null) {
// If there is a seed provided, create a random number with that seed
// and fill the byte array with random bytes
Random(seed).nextBytes(key)
} else {
// fill the byte array with random bytes
Random.nextBytes(key)
}
return key
}
runBlocking {
// Create the configuration
val config = RealmConfiguration.Builder(setOf(Frog::class))
// Specify the encryption key
.encryptionKey(generatedKey)
.build()
// Open the realm with the configuration
val realm = Realm.open(config)
Log.v("Successfully opened encrypted realm: ${realm.configuration.name}")
}

If your app uses Atlas Device Sync, you can encrypt a synced realm, similar to encrypting a local realm.

To encrypt a synced realm, pass your encryption key to the encryptionKey property in the SyncConfiguration.Builder() used to open the realm.

The following code demonstrates how to open an encrypted synced realm:

val syncConfig = SyncConfiguration.Builder(user, setOf(Frog::class))
.initialSubscriptions { realm ->
add(realm.query<Frog>())
}
// Specify the encryption key
.encryptionKey(generatedKey)
.build()
val realm = Realm.open(syncConfig)
Log.v("Successfully opened encrypted realm: ${realm.configuration.name}")

Refer to Configure & Open a Synced Realm - Kotlin SDK for more information.

Realm only encrypts the data on the device and stores the data unencrypted in your Atlas data source. Any users with authorized access to the Atlas data source can read the data, but the following still applies:

  • Users must have the correct read permissions to read the synced data.

  • Data stored in Atlas is always encrypted at a volume (disk) level.

  • The transfer between client and server is always fully encrypted.

You can also enable Customer Key Management to encrypt stored Atlas data using your cloud provider's key (e.g. AWS KMS, Azure Key Vault, Google Cloud KMS).

If you need unique keys for each user of your application, you can use an OAuth provider or use one of the Realm authentication providers and an authentication trigger to create a 64-bit key and store that key in a user object.

You can also encrypt the App Services App metadata that Realm stores on the device.

To learn more, refer to Encrypt App Metadata.

You must pass the same encryption key every time you open the encrypted realm. If you don't provide a key or specify the wrong key for an encrypted realm, the Realm SDK throws an error.

Apps should store the encryption key securely, typically in the target platform's secure key/value storage, so that other apps cannot read the key. For example, you can use the Android Keystore system or Apple's Keychain. It is the developer's responsibility to ensure that attackers cannot access the key.

Reads and writes on encrypted realms can be up to 10% slower than unencrypted realms.

Changed in version 10.8.0.

Starting with Realm Kotlin SDK version 10.8.0, Realm supports opening the same encrypted realm in multiple processes.

If your app uses Realm Kotlin SDK version 10.7.1 or earlier, attempting to open an encrypted realm from multiple processes throws this error: Encrypted interprocess sharing is currently unsupported.

← Delete a Realm - Kotlin SDK