Storing data locally is a common task for mobile applications. There are many convenient solutions that allow storing data persistently, for example SQLiteDatabase and Realm. These systems can be initialized with a secret key in order to store the data encrypted.

The encryption key is meant to stay secret and should not be hard-coded in the application as it would mean that:

There are different approaches how the key can be provided to encrypt and decrypt the database. One of the most convinient way to is to rely on EncryptedSharedPreferences to store encryption keys. It can also be provided dynamically by the user of the application or fetched from a remote server.

Noncompliant Code Example

SQLCipher

String key = "gb09ym9ydoolp3w886d0tciczj6ve9kszqd65u7d126040gwy86xqimjpuuc788g";
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("test.db", key, null); // Noncompliant

Realm

String key = "gb09ym9ydoolp3w886d0tciczj6ve9kszqd65u7d126040gwy86xqimjpuuc788g";
RealmConfiguration config = new RealmConfiguration.Builder();
    .encryptionKey(key.toByteArray()) // Noncompliant
    .build();
Realm realm = Realm.getInstance(config);

Compliant Solution

SQLCipher

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("test.db", getKey(), null);

Realm

RealmConfiguration config = new RealmConfiguration.Builder()
    .encryptionKey(getKey())
    .build();
Realm realm = Realm.getInstance(config);

See