{"id":13611083,"url":"https://github.com/osipxd/encrypted-datastore","last_synced_at":"2025-04-04T22:08:15.675Z","repository":{"id":57744348,"uuid":"416317697","full_name":"osipxd/encrypted-datastore","owner":"osipxd","description":"Extensions to store DataStore in EncryptedFile","archived":false,"fork":false,"pushed_at":"2024-10-21T16:54:32.000Z","size":392,"stargazers_count":151,"open_issues_count":11,"forks_count":11,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-10-22T06:03:22.410Z","etag":null,"topics":["android","datastore","encrypted","encryption","security","tink"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/osipxd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"security-crypto-datastore-preferences/api/security-crypto-datastore-preferences.api","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-10-12T11:56:33.000Z","updated_at":"2024-10-14T08:01:07.000Z","dependencies_parsed_at":"2024-04-16T01:27:38.876Z","dependency_job_id":"5869491f-9e14-4346-b52c-e348039b0d48","html_url":"https://github.com/osipxd/encrypted-datastore","commit_stats":{"total_commits":57,"total_committers":1,"mean_commits":57.0,"dds":0.0,"last_synced_commit":"9cefd66c66fccb75070f218c104b376269a74017"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osipxd%2Fencrypted-datastore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osipxd%2Fencrypted-datastore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osipxd%2Fencrypted-datastore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osipxd%2Fencrypted-datastore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/osipxd","download_url":"https://codeload.github.com/osipxd/encrypted-datastore/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247256112,"owners_count":20909240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","datastore","encrypted","encryption","security","tink"],"created_at":"2024-08-01T19:01:51.631Z","updated_at":"2025-04-04T22:08:15.662Z","avatar_url":"https://github.com/osipxd.png","language":"Kotlin","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"readme":"# Encrypted DataStore\n[![Version](https://img.shields.io/maven-central/v/io.github.osipxd/encrypted-datastore?style=flat-square)][mavenCentral] [![License](https://img.shields.io/github/license/osipxd/encrypted-datastore?style=flat-square)][license]\n\nExtensions to store DataStore into `EncryptedFile`.\n\n\u003e [!WARNING]\n\u003e This library will continue to be maintained, but active development will cease when an official DataStore encryption solution is released by Google.\n\u003e Support the development of this feature by voting for it on the issue tracker: [b/167697691](https://issuetracker.google.com/issues/167697691).\n\n---\n\n## Installation\n\nAdd the dependency:\n\n```kotlin\nrepositories {\n    mavenCentral()\n    google()\n}\n\ndependencies {\n    implementation(\"io.github.osipxd:security-crypto-datastore:1.1.1-beta03\")\n    // Or, if you want to use Preferences DataStore:\n    implementation(\"io.github.osipxd:security-crypto-datastore-preferences:1.1.1-beta03\")\n}\n```\n\n\u003e **Dependencies:**\n\u003e - `security-crypto` [1.0.0](https://developer.android.com/jetpack/androidx/releases/security#1.0.0)\n\u003e - `datastore` [1.1.1](https://developer.android.com/jetpack/androidx/releases/datastore#1.1.1)\n\u003e - `tink` [1.13.0](https://github.com/tink-crypto/tink-java/releases/tag/v1.13.0)\n\n\u003e [!NOTE]\n\u003e Ensure that the version of this library aligns with the DataStore library version used in your project.\n\n## Usage\n\nTo create an encrypted DataStore, simply replace the `dataStore` method with `encryptedDataStore` when setting up your delegate:\n\n```kotlin\n// At the top level of your Kotlin file:\nval Context.settingsDataStore: DataStore\u003cSettings\u003e by encryptedDataStore(\n    fileName = \"settings.pb\",\n    serializer = SettingsSerializer\n)\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eOr, if you want full control over \u003ccode\u003eEncryptedFile\u003c/code\u003e creation\u003c/summary\u003e\n\n```kotlin\nval settingsDataStore: DataStore\u003cSettings\u003e = DataStoreFactory.createEncrypted(SettingsSerializer) {\n    EncryptedFile.Builder(\n        context.dataStoreFile(\"settings.pb\"),\n        context,\n        MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),\n        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB\n    ).build()\n}\n```\n\u003c/details\u003e\n\nSimilarly, you can create Preferences DataStore:\n\n```kotlin\n// At the top level of your Kotlin file:\nval Context.dataStore by encryptedPreferencesDataStore(name = \"settings\")\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eOr, if you want full control over \u003ccode\u003eEncryptedFile\u003c/code\u003e creation\u003c/summary\u003e\n\n```kotlin\nval dataStore: DataStore\u003cPreferences\u003e = PreferenceDataStoreFactory.createEncrypted {\n    EncryptedFile.Builder(\n        context.preferencesDataStoreFile(\"settings\"),\n        context,\n        MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),\n        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB\n    ).build()\n}\n```\n\u003c/details\u003e\n\nOnce your encrypted DataStore is configured, you can use it in the same manner as a regular DataStore.\nFor usage guides and examples, refer to the [DataStore documentation](https://developer.android.com/topic/libraries/architecture/datastore).\n\n## Migration\n\n### Migrating from DataStoreFactory to delegate usage\n\nIf you are starting with the following code:\n\n```kotlin\nval dataStore = DataStoreFactory.createEncrypted(serializer) {\n    EncryptedFile.Builder(\n        context.dataStoreFile(\"filename\"),\n        context,\n        MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),\n        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB\n    ).build()\n}\n```\n\nTo simplify the creation of DataStore using a delegate, follow these steps:\n\n1. Move the field to the top level of your Kotlin file and convert it into an extension on `Context`.\n2. Replace `DataStoreFactory.createEncrypted` with `encryptedDataStore`.\n\n```kotlin\nval Context.dataStore by encryptedDataStore(\n    fileName = \"filename\", // Keep file the same\n    serializer = serializer,\n)\n```\n\n\u003e [!NOTE]\n\u003e This only will be interchangeable if you have used `context.dataStoreFile(...)` to create the datastore file.\n\u003e If you have custom logic for master key creation, ensure to pass the created master key as the `masterKey` parameter to the delegate.\n\n### Migrating from `encrypted-datastore` to `security-crypto-datastore`\n\nChange the dependency in build script:\n\n```diff\n dependencies {\n-    implementation(\"io.github.osipxd:encrypted-datastore:...\")\n+    implementation(\"io.github.osipxd:security-crypto-datastore:...\")\n }\n```\n\nNew library uses `StreamingAead` instead of `Aead` under the hood, so to not lose the previously encrypted data you should specify `fallbackAead`:\n\n```kotlin\n// This AEAD was used to encrypt DataStore previously, we will use it as fallback\nval aead = AndroidKeysetManager.Builder()\n    .withSharedPref(context, \"master_keyset\", \"master_key_preference\")\n    .withKeyTemplate(KeyTemplates.get(\"AES256_GCM\"))\n    .withMasterKeyUri(\"android-keystore://master_key\")\n    .build()\n    .keysetHandle\n    .getPrimitive(Aead::class.java)\n```\n\nThe old code to create DataStore was looking like this:\n\n```kotlin\nval dataStore = DataStoreFactory.create(serializer.encrypted(aead)) {\n    context.dataStoreFile(\"filename\")\n}\n```\n\nThe new code will look like this:\n\n```kotlin\n// At the top level of your Kotlin file:\nval Context.dataStore by encryptedDataStore(\n    fileName = \"filename\", // Keep file the same\n    serializer = serializer,\n    encryptionOptions = {\n        // Specify fallback Aead to make it possible to decrypt data encrypted with it\n        fallbackAead = aead\n    }\n)\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eOr, if you want full control over \u003ccode\u003eEncryptedFile\u003c/code\u003e creation\u003c/summary\u003e\n\n```kotlin\nval dataStore = DataStoreFactory.createEncrypted(\n    serializer = serializer,\n    encryptionOptions = { fallbackAead = aead }\n) {\n    EncryptedFile.Builder(\n        context.dataStoreFile(\"filename\"), // Keep file the same\n        context,\n        MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),\n        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB\n    ).build()\n}\n```\n\u003c/details\u003e\n\n### Thanks\n\n- Artem Kulakov ([Fi5t]), for his [example][secured-datastore] of DataStore encryption.\n- Gods of Kotlin, for posibility to [hack] `internal` visibility modifier \n\n## License\n\n[MIT][license]\n\n\n[mavenCentral]: https://search.maven.org/artifact/io.github.osipxd/encrypted-datastore\n[license]: LICENSE\n\n[tink]: https://github.com/tink-crypto/tink-java\n[secured-datastore]: https://github.com/Fi5t/secured-datastore\n[fi5t]: https://github.com/Fi5t\n[hack]: encrypted-datastore-preferences/src/main/java/io/github/osipxd/datastore/encrypted/PreferenceDataStoreHack.java\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosipxd%2Fencrypted-datastore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fosipxd%2Fencrypted-datastore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosipxd%2Fencrypted-datastore/lists"}