Skip to content

Latest commit

 

History

History
176 lines (142 loc) · 5.18 KB

README.md

File metadata and controls

176 lines (142 loc) · 5.18 KB

Encrypted DataStore

Version License

Extensions to store DataStore in EncryptedFile.

⚠️ This tiny library will be maintained until an official solution for DataStore encryption will be released by Google.
Vote for this feature on issue tracker: b/167697691


Installation

Add the dependency:

repositories {
    mavenCentral()
    google()
}

dependencies {
    implementation("io.github.osipxd:security-crypto-datastore:1.0.0-alpha03")
    // Or, if you want to use Preferences DataStore:
    implementation("io.github.osipxd:security-crypto-datastore-preferences:1.0.0-alpha03")
}

Dependencies:

Usage

To create encrypted DataStore, just use method DataStoreFactory.createEncryptred instead of create and provide EncryptedFile instead of File:

val dataStore = DataStoreFactory.createEncrypted(serializer) {
    EncryptedFile.Builder(
        context.dataStoreFile("filename"),
        context,
        MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
    ).build()
}
Or even simpler, if you use security-crypto-ktx:1.1.0
val dataStore = DataStoreFactory.createEncrypted(serializer) {
    EncryptedFile(
        context = context,
        file = context.dataStoreFile("filename"),
        masterKey = MasterKey(context)
    )
}

Similarly, you can create Preferences DataStore:

val dataStore = DataStoreFactory.createEncrypted(serializer) {
    EncryptedFile.Builder(
        // The file should have extension .preferences_pb
        context.dataStoreFile("filename.preferences_pb"),
        context,
        MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
    ).build()
}
Or even simpler, if you use security-crypto-ktx:1.1.0
val dataStore = PreferenceDataStoreFactory.createEncrypted {
    EncryptedFile(
        context = context,
        // The file should have extension .preferences_pb
        file = context.dataStoreFile("filename.preferences_pb"),
        masterKey = MasterKey(context)
    )
}

Migration

Migrate from encrypted-datastore to security-crypto-datastore

Change the dependency in build script:

 dependencies {
-    implementation("io.github.osipxd:encrypted-datastore:...")
+    implementation("io.github.osipxd:security-crypto-datastore:...")
 }

New library uses StreamingAead instead of Aead under the hood, so to not lose the previously encrypted data you should specify fallbackAead:

// This AEAD was used to encrypt DataStore previously, we will use it as fallback
val aead = AndroidKeysetManager.Builder()
    .withSharedPref(context, "master_keyset", "master_key_preference")
    .withKeyTemplate(KeyTemplates.get("AES256_GCM"))
    .withMasterKeyUri("android-keystore://master_key")
    .build()
    .keysetHandle
    .getPrimitive(Aead::class.java)

The old code to create DataStore was looking like this:

val dataStore = DataStoreFactory.create(serializer.encrypted(aead)) {
    context.dataStoreFile("filename")
}

The new code will look like this:

val dataStore = DataStoreFactory.createEncrypted(
    serializer,
    encryptionOptions = {
        // Specify fallback Aead to make it possible to decrypt data encrypted with it
        fallbackAead = aead
    }
) {
    EncryptedFile.Builder(
        context.dataStoreFile("filename"), // Keep the same file
        context,
        MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
    ).build()
}
Or even simpler, if you use security-crypto-ktx:1.1.0
val dataStore = DataStoreFactory.createEncrypted(
    serializer,
    encryptionOptions = { fallbackAead = aead }
) {
    EncryptedFile(
        context = context,
        file = context.dataStoreFile("filename"), // Keep the same file
        masterKey = MasterKey(context)
    )
}

Thanks

  • Artem Kulakov (Fi5t), for his example of DataStore encryption.
  • Gods of Kotlin, for posibility to hack internal visibility modifier

License

MIT