android: StrongBox for new keystore keys, show key storage level (#7637)

* android: create new keystore keys in StrongBox

* android: show keystore key storage level

* ui: save keystore key before marking it stored

* android: show keystore storage level in the footer text instead of a separate row

* android: return keystore storage label, drop enum

---------

Co-authored-by: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com>
This commit is contained in:
sh
2026-10-04 10:47:46 +01:00
committed by GitHub
co-authored by Narasimha-sc
parent 1a969a6cb9
commit be05a46628
42 changed files with 92 additions and 44 deletions
@@ -1,8 +1,11 @@
package chat.simplex.common.platform
import android.annotation.SuppressLint
import android.os.Build
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyInfo
import android.security.keystore.KeyProperties
import android.security.keystore.StrongBoxUnavailableException
import chat.simplex.common.views.helpers.AlertManager
import chat.simplex.common.views.helpers.generalGetString
import chat.simplex.res.MR
@@ -68,15 +71,44 @@ internal class Cryptor: CryptorInterface {
keyStore.deleteEntry(alias)
}
override fun keyStorage(alias: String): String? {
val secretKey = getSecretKey(alias) ?: return null
val keyInfo = SecretKeyFactory.getInstance(secretKey.algorithm, "AndroidKeyStore").getKeySpec(secretKey, KeyInfo::class.java) as KeyInfo
val storage = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
when (keyInfo.securityLevel) {
KeyProperties.SECURITY_LEVEL_STRONGBOX -> MR.strings.keystore_key_storage_strongbox
KeyProperties.SECURITY_LEVEL_TRUSTED_ENVIRONMENT -> MR.strings.keystore_key_storage_tee
KeyProperties.SECURITY_LEVEL_SOFTWARE -> MR.strings.keystore_key_storage_software
else -> return null
}
} else {
// isInsideSecureHardware does not distinguish StrongBox, which createSecretKey only requests on API 31+
@Suppress("DEPRECATION")
if (keyInfo.isInsideSecureHardware) MR.strings.keystore_key_storage_tee else MR.strings.keystore_key_storage_software
}
return generalGetString(storage)
}
private fun createSecretKey(alias: String): SecretKey? {
if (keyStore.containsAlias(alias)) return getSecretKey(alias)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
try {
return generateKey(keySpec(alias).setIsStrongBoxBacked(true))
} catch (e: StrongBoxUnavailableException) {
Log.i(TAG, "StrongBox is unavailable, using default keystore: ${e.message}")
}
}
return generateKey(keySpec(alias))
}
private fun keySpec(alias: String): KeyGenParameterSpec.Builder =
KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(BLOCK_MODE)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
private fun generateKey(spec: KeyGenParameterSpec.Builder): SecretKey {
val keyGenerator: KeyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM, "AndroidKeyStore")
keyGenerator.init(
KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(BLOCK_MODE)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build()
)
keyGenerator.init(spec.build())
return keyGenerator.generateKey()
}
@@ -59,6 +59,7 @@ actual fun DatabaseEncryptionFooter(
useKeychain: MutableState<Boolean>,
chatDbEncrypted: Boolean?,
storedKey: MutableState<Boolean>,
keyStorage: String?,
initialRandomDBPassphrase: MutableState<Boolean>,
migration: Boolean,
) {
@@ -66,7 +67,7 @@ actual fun DatabaseEncryptionFooter(
SectionTextFooter(generalGetString(MR.strings.database_is_not_encrypted))
} else if (useKeychain.value) {
if (storedKey.value) {
SectionTextFooter(generalGetString(MR.strings.keychain_is_storing_securely))
SectionTextFooter(String.format(generalGetString(MR.strings.keychain_is_storing_securely), keyStorage?.let { " ($it)" } ?: ""))
if (initialRandomDBPassphrase.value && !migration) {
SectionTextFooter(generalGetString(MR.strings.encrypted_with_random_passphrase))
} else {
@@ -4,6 +4,7 @@ interface CryptorInterface {
fun decryptData(data: ByteArray, iv: ByteArray, alias: String): String?
fun encryptText(text: String, alias: String): Pair<ByteArray, ByteArray>
fun deleteKey(alias: String)
fun keyStorage(alias: String): String?
}
expect val cryptor: CryptorInterface
@@ -44,6 +44,7 @@ fun DatabaseEncryptionView(m: ChatModel, migration: Boolean) {
val useKeychain = remember { mutableStateOf(appPrefs.storeDBPassphrase.get()) }
val initialRandomDBPassphrase = remember { mutableStateOf(appPrefs.initialRandomDBPassphrase.get()) }
val storedKey = remember { val key = DatabaseUtils.ksDatabasePassword.get(); mutableStateOf(key != null && key != "") }
val keyStorage = remember(storedKey.value) { if (storedKey.value) DatabaseUtils.ksDatabasePassword.storage() else null }
// Do not do rememberSaveable on current key to prevent saving it on disk in clear text
val currentKey = remember { mutableStateOf(if (initialRandomDBPassphrase.value) DatabaseUtils.ksDatabasePassword.get() ?: "" else "") }
val newKey = rememberSaveable { mutableStateOf("") }
@@ -60,6 +61,7 @@ fun DatabaseEncryptionView(m: ChatModel, migration: Boolean) {
newKey,
confirmNewKey,
storedKey,
keyStorage,
initialRandomDBPassphrase,
progressIndicator,
migration,
@@ -105,6 +107,7 @@ fun DatabaseEncryptionLayout(
newKey: MutableState<String>,
confirmNewKey: MutableState<String>,
storedKey: MutableState<Boolean>,
keyStorage: String?,
initialRandomDBPassphrase: MutableState<Boolean>,
progressIndicator: MutableState<Boolean>,
migration: Boolean,
@@ -196,7 +199,7 @@ fun DatabaseEncryptionLayout(
}
Column {
DatabaseEncryptionFooter(useKeychain, chatDbEncrypted, storedKey, initialRandomDBPassphrase, migration)
DatabaseEncryptionFooter(useKeychain, chatDbEncrypted, storedKey, keyStorage, initialRandomDBPassphrase, migration)
}
SectionBottomSpacer()
}
@@ -254,6 +257,7 @@ expect fun DatabaseEncryptionFooter(
useKeychain: MutableState<Boolean>,
chatDbEncrypted: Boolean?,
storedKey: MutableState<Boolean>,
keyStorage: String?,
initialRandomDBPassphrase: MutableState<Boolean>,
migration: Boolean,
)
@@ -460,12 +464,13 @@ suspend fun encryptDatabase(
if (migration) {
appPreferences.storeDBPassphrase.set(useKeychain.value)
}
resetFormAfterEncryption(m, initialRandomDBPassphrase, currentKey, newKey, confirmNewKey, storedKey, useKeychain.value)
if (useKeychain.value) {
DatabaseUtils.ksDatabasePassword.set(new)
} else {
removePassphraseFromKeyChain(useKeychain, storedKey, migration)
}
// DatabaseEncryptionView reads key storage when storedKey changes, so storedKey is updated after the key is saved
resetFormAfterEncryption(m, initialRandomDBPassphrase, currentKey, newKey, confirmNewKey, storedKey, useKeychain.value)
operationEnded(m, progressIndicator) {
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.database_encrypted))
}
@@ -540,6 +545,7 @@ fun PreviewDatabaseEncryptionLayout() {
newKey = remember { mutableStateOf("") },
confirmNewKey = remember { mutableStateOf("") },
storedKey = remember { mutableStateOf(true) },
keyStorage = stringResource(MR.strings.keystore_key_storage_strongbox),
initialRandomDBPassphrase = remember { mutableStateOf(true) },
progressIndicator = remember { mutableStateOf(false) },
migration = false,
@@ -38,6 +38,8 @@ object DatabaseUtils {
passphrase.set(null)
initVector.set(null)
}
fun storage(): String? = cryptor.keyStorage(alias)
}
fun hasAtLeastOneDatabase(rootDir: String): Boolean =
@@ -453,7 +453,7 @@ private fun MutableState<MigrationToState?>.PassphraseEnteringView(currentKey: S
}
}
) {}
DatabaseEncryptionFooter(useKeychain, chatDbEncrypted = true, remember { mutableStateOf(false) }, remember { mutableStateOf(false) }, true)
DatabaseEncryptionFooter(useKeychain, chatDbEncrypted = true, remember { mutableStateOf(false) }, null, remember { mutableStateOf(false) }, true)
}
if (verifyingPassphrase.value) {
ProgressView()
@@ -43,7 +43,7 @@
<string name="callstatus_accepted">قُبلت المكالمة</string>
<string name="allow_calls_only_if">اسمح بالمكالمات فقط إذا سمحت جهة اتصالك بذلك.</string>
<string name="allow_message_reactions_only_if">اسمح بردود الفعل على الرسائل فقط إذا سمحت جهة اتصالك بذلك.</string>
<string name="keychain_is_storing_securely">يتم استخدام Android Keystore لتخزين عبارة المرور بشكل آمن - فهو يسمح لخدمة الإشعارات بالعمل.</string>
<string name="keychain_is_storing_securely">يتم استخدام Android Keystore%s لتخزين عبارة المرور بشكل آمن - فهو يسمح لخدمة الإشعارات بالعمل.</string>
<string name="empty_chat_profile_is_created">يتم إنشاء ملف تعريف دردشة فارغ بالاسم المقدم، ويفتح التطبيق كالمعتاد.</string>
<string name="answer_call">أجب الاتصال</string>
<string name="chat_preferences_always">دائمًا</string>
@@ -1642,6 +1642,9 @@
<!-- DatabaseEncryptionView.kt -->
<string name="save_passphrase_in_keychain">Save passphrase in Keystore</string>
<string name="save_passphrase_in_settings">Save passphrase in settings</string>
<string name="keystore_key_storage_strongbox">Secure element</string>
<string name="keystore_key_storage_tee">TEE</string>
<string name="keystore_key_storage_software">Software</string>
<string name="database_encrypted">Database encrypted!</string>
<string name="error_encrypting_database">Error encrypting database</string>
<string name="remove_passphrase_from_keychain">Remove passphrase from Keystore?</string>
@@ -1658,7 +1661,7 @@
<string name="set_passphrase">Set passphrase</string>
<string name="enter_correct_current_passphrase">Please enter correct current passphrase.</string>
<string name="database_is_not_encrypted">Your chat database is not encrypted - set passphrase to protect it.</string>
<string name="keychain_is_storing_securely">Android Keystore is used to securely store passphrase - it allows notification service to work.</string>
<string name="keychain_is_storing_securely">Android Keystore%s is used to securely store passphrase - it allows notification service to work.</string>
<string name="settings_is_storing_in_clear_text">The passphrase is stored in settings as plaintext.</string>
<string name="encrypted_with_random_passphrase">Database is encrypted using a random passphrase, you can change it.</string>
<string name="impossible_to_recover_passphrase"><![CDATA[<b>Please note</b>: you will NOT be able to recover or change passphrase if you lose it.]]></string>
@@ -78,7 +78,7 @@
<string name="allow_your_contacts_to_send_voice_messages">Позволи на вашите контакти да изпращат гласови съобщения.</string>
<string name="all_your_contacts_will_remain_connected_update_sent">Всички ваши контакти ще останат свързани. Актуализацията на профила ще бъде изпратена до вашите контакти.</string>
<string name="notifications_mode_service">Винаги включен</string>
<string name="keychain_is_storing_securely">Android Keystore се използва за сигурно съхраняване на паролата - тоа позволява на услугата за известия да работи.</string>
<string name="keychain_is_storing_securely">Android Keystore%s се използва за сигурно съхраняване на паролата - тоа позволява на услугата за известия да работи.</string>
<string name="empty_chat_profile_is_created">Създаен беше празен профил за чат с предоставеното име и приложението се отвари както обикновено.</string>
<string name="notifications_mode_off_desc">Приложението може да получава известия само когато работи, няма да се стартира услуга във фонов режим</string>
<string name="settings_section_title_icon">Икона на приложението</string>
@@ -125,7 +125,7 @@
<string name="settings_section_title_icon">Icona aplicació</string>
<string name="privacy_media_blur_radius">Desenfocar els mitjans</string>
<string name="settings_section_title_calls">Trucades</string>
<string name="keychain_is_storing_securely">Android Keystore s\'utilitza per emmagatzemar de manera segura la frase de contrasenya: permet que el servei de notificacions funcioni.</string>
<string name="keychain_is_storing_securely">Android Keystore%s s\'utilitza per emmagatzemar de manera segura la frase de contrasenya: permet que el servei de notificacions funcioni.</string>
<string name="keychain_allows_to_receive_ntfs">Android Keystore s\'utilitzarà per emmagatzemar de manera segura la frase de contrasenya després de reiniciar l\'aplicació o canviar la frase de contrasenya; permetrà rebre notificacions.</string>
<string name="cannot_access_keychain">No es pot accedir a Keystore per desar la contrasenya de la base de dades</string>
<string name="impossible_to_recover_passphrase"><![CDATA[<b>Tingueu en compte</b>: NO podreu recuperar ni canviar la contrasenya si la perdeu.]]></string>
@@ -280,7 +280,7 @@
<string name="update_database_passphrase">Aktualizovat přístupovou frázi</string>
<string name="enter_correct_current_passphrase">Zadejte prosím správnou aktuální přístupovou frázi.</string>
<string name="database_is_not_encrypted">Databáze chatu není šifrována - nastavte přístupovou frázi pro její ochranu.</string>
<string name="keychain_is_storing_securely">K bezpečnému uložení přístupové fráze slouží úložiště klíčů Android - umožňuje fungování služby oznámení.</string>
<string name="keychain_is_storing_securely">K bezpečnému uložení přístupové fráze slouží úložiště klíčů Android%s - umožňuje fungování služby oznámení.</string>
<string name="impossible_to_recover_passphrase"><![CDATA[<b>Upozornění</b>: pokud přístupovou frázi ztratíte, NEBUDE možné ji obnovit ani změnit.]]></string>
<string name="database_will_be_encrypted_and_passphrase_stored">Databáze bude zašifrována a přístupová fráze bude uložena v úložišti klíčů.</string>
<string name="store_passphrase_securely">Přístupovou frázi uložte bezpečně, v případě její ztráty ji NEBUDE možné změnit.</string>
@@ -147,7 +147,7 @@
<string name="network_smp_proxy_mode_always_description">Brug altid privat routing.</string>
<string name="always_use_relay">Brug altid relæ</string>
<string name="rcv_group_and_other_events">og %d andre begivenheder</string>
<string name="keychain_is_storing_securely">Android Keystore bruges til sikkert at opbevare adgangssæt - det giver Notification Service mulighed for at arbejde.</string>
<string name="keychain_is_storing_securely">Android Keystore%s bruges til sikkert at opbevare adgangssæt - det giver Notification Service mulighed for at arbejde.</string>
<string name="keychain_allows_to_receive_ntfs">Android Keystore vil blive brugt til sikkert at gemme adgangssæt, når du genstarter appen eller skifter adgangssætning - det giver mulighed for at modtage meddelelser.</string>
<string name="empty_chat_profile_is_created">En tom chatprofil med det angivne navn oprettes, og appen åbnes som sædvanligt.</string>
<string name="connect__a_new_random_profile_will_be_shared">En ny tilfældig profil deles.</string>
@@ -583,7 +583,7 @@
<string name="update_database_passphrase">Datenbank-Passwort aktualisieren</string>
<string name="enter_correct_current_passphrase">Bitte geben Sie das korrekte, aktuelle Passwort ein.</string>
<string name="database_is_not_encrypted">Ihre Chat-Datenbank ist nicht verschlüsselt. Bitte legen Sie ein Passwort fest, um sie zu schützen.</string>
<string name="keychain_is_storing_securely">Der Android-Keystore wird verwendet, um das Passwort sicher zu speichern. Dies ermöglicht die ordentliche Funktion des Benachrichtigungsdienstes.</string>
<string name="keychain_is_storing_securely">Der Android-Keystore%s wird verwendet, um das Passwort sicher zu speichern. Dies ermöglicht die ordentliche Funktion des Benachrichtigungsdienstes.</string>
<string name="encrypted_with_random_passphrase">Die Datenbank wird mit einem zufälligen Passwort verschlüsselt, Sie können es ändern.</string>
<string name="impossible_to_recover_passphrase"><![CDATA[<b>Bitte beachten Sie</b>: Sie können das Passwort NICHT wiederherstellen oder ändern, wenn Sie es vergessen haben oder verlieren.]]></string>
<string name="keychain_allows_to_receive_ntfs">Der Android-Keystore wird verwendet, um das Passwort sicher zu speichern, nachdem Sie die App neu gestartet oder das Passwort geändert haben – dies ermöglicht den Empfang von Benachrichtigungen.</string>
@@ -242,7 +242,7 @@
<string name="alert_title_msg_bad_hash">Κακό μήνυμα hash</string>
<string name="privacy_media_blur_radius">Θάμπωση των μέσων</string>
<string name="settings_section_title_chat_database">Βάση δεδομένων συνομιλίας</string>
<string name="keychain_is_storing_securely">Το Android Keystore χρησιμοποιείται για την ασφαλή αποθήκευση της φράσης πρόσβασης - επιτρέπει την υπηρεσία ειδοποιήσεων να λειτουργεί.</string>
<string name="keychain_is_storing_securely">Το Android Keystore%s χρησιμοποιείται για την ασφαλή αποθήκευση της φράσης πρόσβασης - επιτρέπει την υπηρεσία ειδοποιήσεων να λειτουργεί.</string>
<string name="member_info_member_blocked">αποκλεισμένος</string>
<string name="member_blocked_by_admin">Αποκλεισμένος από τον διαχειριστή</string>
<string name="cant_call_contact_alert_title">Δεν είναι δυνατή η κλήση επαφής</string>
@@ -51,7 +51,7 @@
<string name="users_delete_all_chats_deleted">Se eliminarán todos los chats y mensajes. ¡No puede deshacerse!</string>
<string name="accept_feature">Aceptar</string>
<string name="allow_to_send_disappearing">Se permiten mensajes temporales.</string>
<string name="keychain_is_storing_securely">Android Keystore se usará para almacenar la frase de contraseña de forma segura - permite que el servicio de notificaciones funcione.</string>
<string name="keychain_is_storing_securely">Android Keystore%s se usará para almacenar la frase de contraseña de forma segura - permite que el servicio de notificaciones funcione.</string>
<string name="users_add">Añadir perfil</string>
<string name="color_primary">Color</string>
<string name="allow_your_contacts_irreversibly_delete">Permites que tus contactos eliminan irreversiblemente los mensajes enviados. (24 horas)</string>
@@ -994,7 +994,7 @@
<string name="encrypt_database">رمزنگاری</string>
<string name="update_database_passphrase">به‌روزرسانی عبارت عبور پایگاه داده</string>
<string name="set_passphrase">تعیین عبارت عبور</string>
<string name="keychain_is_storing_securely">از مخزن کلید اندروید برای ذخیره امن عبارت عبور استفاده می‌شود - به سرویس اعلان اجازه عمل می‌دهد.</string>
<string name="keychain_is_storing_securely">از مخزن کلید اندروید%s برای ذخیره امن عبارت عبور استفاده می‌شود - به سرویس اعلان اجازه عمل می‌دهد.</string>
<string name="you_have_to_enter_passphrase_every_time">باید هر بار که برنامه شروع می‌شود عبارت عبور را وارد کنید - در دستگاه ذخیره نمی‌شود.</string>
<string name="encrypted_database">پایگاه داده رمزنگاری شده</string>
<string name="icon_descr_contact_checked">مخاطب بررسی شد</string>
@@ -115,7 +115,7 @@
<string name="delete_files_and_media_question">Poistetaanko tiedostot ja media\?</string>
<string name="total_files_count_and_size">%d tiedosto(a), joiden kokonaiskoko on %s</string>
<string name="current_passphrase">Nykyinen tunnuslause…</string>
<string name="keychain_is_storing_securely">Android Keystorea käytetään salalauseen turvalliseen tallentamiseen - se mahdollistaa ilmoituspalvelun toiminnan.</string>
<string name="keychain_is_storing_securely">Android Keystorea%s käytetään salalauseen turvalliseen tallentamiseen - se mahdollistaa ilmoituspalvelun toiminnan.</string>
<string name="encrypted_with_random_passphrase">Tietokanta on salattu satunnaisella tunnuslauseella, voit muuttaa sitä.</string>
<string name="database_error">Tietokantavirhe</string>
<string name="database_passphrase_is_required">Keskustelun avaamiseen tarvitaan tietokannan tunnuslause.</string>
@@ -584,7 +584,7 @@
<string name="new_passphrase">Nouvelle phrase secrète…</string>
<string name="confirm_new_passphrase">Confirmer la nouvelle phrase secrète…</string>
<string name="update_database_passphrase">Mise à jour de la phrase secrète de la base de données</string>
<string name="keychain_is_storing_securely">Le Keystore d\'Android est utilisé pour stocker en toute sécurité la phrase secrète - elle permet au service de notification de fonctionner.</string>
<string name="keychain_is_storing_securely">Le Keystore d\'Android%s est utilisé pour stocker en toute sécurité la phrase secrète - elle permet au service de notification de fonctionner.</string>
<string name="you_have_to_enter_passphrase_every_time">Vous devez saisir la phrase secrète à chaque fois que l\'application démarre - elle n\'est pas stockée sur l\'appareil.</string>
<string name="encrypt_database_question">Chiffrer la base de données \?</string>
<string name="change_database_passphrase_question">Changer la phrase secrète de la base de données \?</string>
@@ -41,7 +41,7 @@
<string name="icon_descr_cancel_link_preview">hivatkozáselőnézet visszavonása</string>
<string name="network_session_mode_user_description"><![CDATA[<b>Az összes csevegési profiljához az alkalmazásban</b> külön TCP-kapcsolat (és SOCKS-hitelesítési adat) lesz használva.]]></string>
<string name="both_you_and_your_contact_can_send_disappearing">Mindkét fél küldhet eltűnő üzeneteket.</string>
<string name="keychain_is_storing_securely">Az Android Keystore-t a jelmondat biztonságos tárolására használják – lehetővé teszi az értesítési szolgáltatás működését.</string>
<string name="keychain_is_storing_securely">Az Android Keystore-t%s a jelmondat biztonságos tárolására használják – lehetővé teszi az értesítési szolgáltatás működését.</string>
<string name="alert_title_msg_bad_hash">Hibás az üzenet kivonata</string>
<string name="color_background">Háttér</string>
<string name="socks_proxy_setting_limitations"><![CDATA[<b>Megjegyzés</b>: az üzenet- és a fájlátjátszók SOCKS proxyn keresztül kapcsolódnak. A hívások pedig közvetlen kapcsolatot használnak.]]></string>
@@ -987,7 +987,7 @@
<string name="settings_section_title_themes">Tema</string>
<string name="settings_section_title_delivery_receipts">Kirim tanda terima kiriman ke</string>
<string name="alert_text_fragment_encryption_out_of_sync_old_database">Hal ini dapat terjadi ketika Anda atau koneksi Anda menggunakan cadangan basis data lama.</string>
<string name="keychain_is_storing_securely">Android Keystore digunakan untuk menyimpan frasa sandi dengan aman - memungkinkan layanan notifikasi berfungsi.</string>
<string name="keychain_is_storing_securely">Android Keystore%s digunakan untuk menyimpan frasa sandi dengan aman - memungkinkan layanan notifikasi berfungsi.</string>
<string name="remove_passphrase">Hapus</string>
<string name="encrypt_database">Enkripsi</string>
<string name="messages_section_title">Pesan</string>
@@ -256,7 +256,7 @@
<string name="error_importing_database">Errore nell\'importazione del database della chat</string>
<string name="group_full_name_field">Nome completo del gruppo:</string>
<string name="full_backup">Backup dei dati dell\'app</string>
<string name="keychain_is_storing_securely">L\'archivio chiavi di Android è usato per memorizzare in modo sicuro la password; permette il funzionamento del servizio di notifica.</string>
<string name="keychain_is_storing_securely">L\'archivio chiavi di Android%s è usato per memorizzare in modo sicuro la password; permette il funzionamento del servizio di notifica.</string>
<string name="allow_your_contacts_to_send_voice_messages">Permetti ai tuoi contatti di inviare messaggi vocali.</string>
<string name="chat_database_deleted">Database della chat eliminato</string>
<string name="settings_section_title_icon">Icona app</string>
@@ -51,7 +51,7 @@
<string name="allow_voice_messages_question">לאפשר הודעות קוליות\?</string>
<string name="allow_your_contacts_to_send_voice_messages">אפשר לאנשי קשר לשלוח הודעות קוליות.</string>
<string name="notifications_mode_service">תמיד פעיל</string>
<string name="keychain_is_storing_securely">ישנו שימוש ב־Android Keystore כדי לאחסן בבטחה את הסיסמה – דבר המאפשר לשירות ההתראות לעבוד.</string>
<string name="keychain_is_storing_securely">ישנו שימוש ב־Android Keystore%s כדי לאחסן בבטחה את הסיסמה – דבר המאפשר לשירות ההתראות לעבוד.</string>
<string name="keychain_allows_to_receive_ntfs">Android Keystore יאחסן בבטחה את הסיסמה לאחר הפעלה מחדש של האפליקציה או שינוי הסיסמה – דבר המאפשר קבלת התראות.</string>
<string name="full_backup">גיבוי נתוני האפליקציה</string>
<string name="settings_section_title_icon">סמל האפליקציה</string>
@@ -61,7 +61,7 @@
<string name="allow_direct_messages">メンバーへのダイレクトメッセージを許可</string>
<string name="allow_to_send_voice">音声メッセージの送信を許可</string>
<string name="notifications_mode_off_desc">アクティブの時のみに通知が出ます。バックグラウンド通知サービスは起動されません。</string>
<string name="keychain_is_storing_securely">Androidキーストアはパスフレーズの保管に使われます。通知機能に必要です。</string>
<string name="keychain_is_storing_securely">Androidキーストア%sはパスフレーズの保管に使われます。通知機能に必要です。</string>
<string name="keychain_allows_to_receive_ntfs">再起動時とパスフレーズ変更時にAndroidキーストアがパスフレーズの保管に使われます。通知機能に必要です。</string>
<string name="answer_call">通話に応答</string>
<string name="settings_section_title_icon">アプリのアイコン</string>
@@ -148,7 +148,7 @@
<string name="allow_irreversible_message_deletion_only_if">대화 상대가 허용하는 경우에만 영구적인 메시지 삭제를 허용합니다. (24 시간)</string>
<string name="all_your_contacts_will_remain_connected">모든 대화 상대가 연결된 상태로 유지됩니다.</string>
<string name="notifications_mode_service">항상 켜기</string>
<string name="keychain_is_storing_securely">Android 암호 저장소는 암호를 안전하게 저장하는 데 사용됩니다 - 알림 서비스가 작동할 수 있습니다.</string>
<string name="keychain_is_storing_securely">Android 암호 저장소%s는 암호를 안전하게 저장하는 데 사용됩니다 - 알림 서비스가 작동할 수 있습니다.</string>
<string name="keychain_allows_to_receive_ntfs">앱을 다시 시작하거나 암호를 변경한 후 Android 암호 저장소를 사용하여 암호를 안전하게 저장합니다. - 알림을 받을 수 있습니다.</string>
<string name="notifications_mode_off_desc">앱이 실행 중일 때만 알림을 받을 수 있으며, 백그라운드 서비스는 시작되지 않습니다.</string>
<string name="full_backup">앱 데이터 백업</string>
@@ -523,7 +523,7 @@
<string name="all_app_data_will_be_cleared">Visi programėlės duomenys bus ištrinti.</string>
<string name="empty_chat_profile_is_created">Sukuriamas tuščias pokalbių profilis nurodytu pavadinimu ir programėlė atveriama kaip įprasta.</string>
<string name="settings_section_title_app">Programėlė</string>
<string name="keychain_is_storing_securely">Saugiam slaptafrazės saugojimui yra naudojama „Android Keystore“ – tai įgalina pranešimų tarnybą veikti.</string>
<string name="keychain_is_storing_securely">Saugiam slaptafrazės saugojimui yra naudojama „Android Keystore“%s – tai įgalina pranešimų tarnybą veikti.</string>
<string name="color_secondary_variant">Papildoma antrinė spalva</string>
<string name="color_primary_variant">Papildomas akcentavimas</string>
<string name="allow_to_send_files">Leisti siųsti failus ir mediją.</string>
@@ -1672,7 +1672,7 @@
<string name="set_passphrase">Iestatīt frāzi</string>
<string name="enter_correct_current_passphrase">Ievadiet pareizo pašreizējo frāzi</string>
<string name="database_is_not_encrypted">Datubāze nav šifrēta</string>
<string name="keychain_is_storing_securely">Atslēgu glabātuve tiek droši glabāta</string>
<string name="keychain_is_storing_securely">Atslēgu glabātuve%s tiek droši glabāta</string>
<string name="settings_is_storing_in_clear_text">Iestatījumi tiek glabāti parastā tekstā</string>
<string name="encrypted_with_random_passphrase">Šifrēts ar nejaušu frāzi</string>
<string name="impossible_to_recover_passphrase"><![CDATA[Nav iespējams atgūt frāzi]]></string>
@@ -117,7 +117,7 @@
<string name="network_smp_proxy_mode_always_description">Bruk alltid privat ruting.</string>
<string name="always_use_relay">Bruk alltid relé</string>
<string name="rcv_group_and_other_events">og %d andre hendelser</string>
<string name="keychain_is_storing_securely">Android Keystore brukes til å lagre passord på en sikker måte – det gjør at varslingstjenesten fungerer.</string>
<string name="keychain_is_storing_securely">Android Keystore%s brukes til å lagre passord på en sikker måte – det gjør at varslingstjenesten fungerer.</string>
<string name="keychain_allows_to_receive_ntfs">Android Keystore brukes til å trygt lagre passordet ditt etter at du restarter appen eller bytter passord - det gjør at du kan motta varsler.</string>
<string name="empty_chat_profile_is_created">En tom chat-profil med navnet du har valgt vil bli laget, og appen åpnes som vanlig.</string>
<string name="connect__a_new_random_profile_will_be_shared">En ny tilfeldig profil vil bli delt.</string>
@@ -79,7 +79,7 @@
<string name="icon_descr_audio_off">Geluid uit</string>
<string name="full_backup">Back-up van app gegevens</string>
<string name="answer_call">Beantwoord oproep</string>
<string name="keychain_is_storing_securely">Android Keychain wordt gebruikt om het wachtwoord veilig op te slaan, hierdoor kan de meldings service werken.</string>
<string name="keychain_is_storing_securely">Android Keychain%s wordt gebruikt om het wachtwoord veilig op te slaan, hierdoor kan de meldings service werken.</string>
<string name="keychain_allows_to_receive_ntfs">Android Keychain wordt gebruikt om het wachtwoord veilig op te slaan nadat u de app opnieuw hebt opgestart of het wachtwoord heeft gewijzigd, hiermee kunt u meldingen ontvangen.</string>
<string name="app_version_code">App build: %s</string>
<string name="notifications_mode_off_desc">App kan alleen meldingen ontvangen wanneer deze actief is, er wordt geen achtergrondservice gestart</string>
@@ -538,7 +538,7 @@
<string name="update_database">Aktualizuj</string>
<string name="update_database_passphrase">Aktualizuj hasło do bazy danych</string>
<string name="database_is_not_encrypted">Twoja baza danych czatu nie jest szyfrowana - ustaw hasło, aby ją chronić.</string>
<string name="keychain_is_storing_securely">Android Keystore służy do bezpiecznego przechowywania hasła - umożliwia działanie usługi powiadomień.</string>
<string name="keychain_is_storing_securely">Android Keystore%s służy do bezpiecznego przechowywania hasła - umożliwia działanie usługi powiadomień.</string>
<string name="keychain_allows_to_receive_ntfs">Android Keystore będzie używany do bezpiecznego przechowywania hasła po ponownym uruchomieniu aplikacji lub zmianie hasła - pozwoli to na otrzymywanie powiadomień.</string>
<string name="impossible_to_recover_passphrase"><![CDATA[<b> Uwaga</b>: NIE będziesz w stanie odzyskać ani zmienić hasła, jeśli je zgubisz.]]></string>
<string name="cannot_access_keychain">Nie można uzyskać dostępu do Keystore w celu zapisania hasła bazy danych</string>
@@ -54,7 +54,7 @@
<string name="call_on_lock_screen">Chamadas na tela de bloqueio:</string>
<string name="icon_descr_audio_on">Áudio ligado</string>
<string name="chat_database_imported">Banco de dados do chat importado</string>
<string name="keychain_is_storing_securely">O Android Keystore é usado para armazenar a senha com segurança. Isso permite que o serviço de notificações funcione.</string>
<string name="keychain_is_storing_securely">O Android Keystore%s é usado para armazenar a senha com segurança. Isso permite que o serviço de notificações funcione.</string>
<string name="keychain_allows_to_receive_ntfs">O Android Keystore será usado para armazenar a senha com segurança após você reiniciar o aplicativo ou alterar a senha, permitindo continuar recebendo notificações.</string>
<string name="cannot_access_keychain">Não é possível acessar a Keystore para salvar a senha do banco de dados</string>
<string name="chat_is_stopped_indication">O chat está parado</string>
@@ -166,7 +166,7 @@
<string name="voice_messages_prohibited">Mensagens de voz proibidas!</string>
<string name="voice_message_with_duration">Mensagem de voz (%1$s)</string>
<string name="app_version_name">Versão da aplicação: v%s</string>
<string name="keychain_is_storing_securely">O Android Keystore é usado para armazenar com segurança a senha - permite que o serviço de notificações funcione.</string>
<string name="keychain_is_storing_securely">O Android Keystore%s é usado para armazenar com segurança a senha - permite que o serviço de notificações funcione.</string>
<string name="keychain_allows_to_receive_ntfs">O Android Keystore será usado para armazenar com segurança a senha depois de voçê reiniciar a aplicação ou alterar a senha - irá permitir receber notificações.</string>
<string name="notifications_will_be_hidden">As notificações serão entregues apenas até à aplicação parar!</string>
<string name="app_version_code">Compilação da aplicação: %s</string>
@@ -93,7 +93,7 @@
<string name="connect_plan_already_joining_the_group">Se alătură deja grupului!</string>
<string name="notifications_mode_service">Mereu pornit</string>
<string name="connect__a_new_random_profile_will_be_shared">Un nou profil aleatoriu va fi distribuit.</string>
<string name="keychain_is_storing_securely">Android Keystore este folosit pentru a stoca în siguranță parola. Acest lucru permite funcționarea serviciului de notificări.</string>
<string name="keychain_is_storing_securely">Android Keystore%s este folosit pentru a stoca în siguranță parola. Acest lucru permite funcționarea serviciului de notificări.</string>
<string name="rcv_group_and_other_events">și %d alte evenimente</string>
<string name="answer_call">Răspunde la apel</string>
<string name="keychain_allows_to_receive_ntfs">Android Keystore va fi folosit pentru a stoca în siguranță parola după ce repornești aplicația sau schimbi parola — acest lucru va permite primirea de notificări.</string>
@@ -585,7 +585,7 @@
<string name="update_database_passphrase">Поменять пароль</string>
<string name="enter_correct_current_passphrase">Пожалуйста, введите правильный пароль.</string>
<string name="database_is_not_encrypted">База данных НЕ зашифрована. Установите пароль, чтобы защитить Ваши данные.</string>
<string name="keychain_is_storing_securely">Android Keystore используется для безопасного хранения пароля - это позволяет стабильно получать уведомления в фоновом режиме.</string>
<string name="keychain_is_storing_securely">Android Keystore%s используется для безопасного хранения пароля - это позволяет стабильно получать уведомления в фоновом режиме.</string>
<string name="encrypted_with_random_passphrase">База данных зашифрована случайным паролем, Вы можете его поменять.</string>
<string name="impossible_to_recover_passphrase"><![CDATA[<b>Внимание</b>: Вы не сможете восстановить или поменять пароль, если потеряете его.]]></string>
<string name="keychain_allows_to_receive_ntfs">Пароль базы данных будет безопасно сохранён в Android Keystore после запуска чата или изменения пароля - это позволит стабильно получать уведомления.</string>
@@ -651,7 +651,7 @@
<string name="set_password_to_export">Nastavte prístupovú frázu pre export</string>
<string name="to_reveal_profile_enter_password">Aby ste odhalili svoj skrytý profil, zadajte celé heslo do vyhľadávacieho poľa na stránke profilov chatov.</string>
<string name="network_proxy_auth_mode_username_password">Vaše prihlasovacie údaje môžu byť zaslané nešifrované.</string>
<string name="keychain_is_storing_securely">Android Keystore je použitý na bezpečné uloženie prístupovej frázy - umožňuje to fungovanie služby oznámení.</string>
<string name="keychain_is_storing_securely">Android Keystore%s je použitý na bezpečné uloženie prístupovej frázy - umožňuje to fungovanie služby oznámení.</string>
<string name="keychain_allows_to_receive_ntfs">Android Keystore bude použitý na bezpečné uloženie prístupovej frázy po reštarte aplikácie alebo zmene prístupovej frázy - umožní to fungovanie služby oznámení.</string>
<string name="impossible_to_recover_passphrase"><![CDATA[<b>Upozornenie</b>: ak stratíte vašu prístupovú frázu, NEBUDE možné ju obnoviť ani zmeniť.]]></string>
<string name="change_database_passphrase_question">Zmeniť prístupovú frázu k databáze?</string>
@@ -23,7 +23,7 @@
<string name="color_primary_variant">เน้นสีเพิ่มเติม</string>
<string name="settings_section_title_icon">ไอคอนแอป</string>
<string name="v5_0_app_passcode">รหัสผ่านแอป</string>
<string name="keychain_is_storing_securely">Android Keystore ใช้เพื่อจัดเก็บรหัสผ่านอย่างปลอดภัย - ซึ่งจะช่วยให้บริการแจ้งเตือนทำงานได้</string>
<string name="keychain_is_storing_securely">Android Keystore%s ใช้เพื่อจัดเก็บรหัสผ่านอย่างปลอดภัย - ซึ่งจะช่วยให้บริการแจ้งเตือนทำงานได้</string>
<string name="keychain_allows_to_receive_ntfs">Android Keystore จะถูกใช้เพื่อจัดเก็บรหัสผ่านอย่างปลอดภัยหลังจากที่คุณรีสตาร์ทแอปหรือเปลี่ยนรหัสผ่าน - ซึ่งจะอนุญาตให้รับบริการแจ้งเตือนได้</string>
<string name="app_version_code">รุ่นแอป: %s</string>
<string name="full_backup">การสํารองข้อมูลแอป</string>
@@ -665,7 +665,7 @@
<string name="v4_2_auto_accept_contact_requests">Bağlanma isteklerini otomatik kabul et</string>
<string name="database_downgrade_warning">Uyarı: Bazı verileri kaybedebilirsin!</string>
<string name="all_your_contacts_will_remain_connected_update_sent">Tüm kişileriniz bağlı kalacaktır. Profil güncellemesi kişilerinize gönderilecektir.</string>
<string name="keychain_is_storing_securely">Android Keystore parolayı güvenli bir şekilde saklamak için kullanılır - bildirim hizmetinin çalışmasını sağlar.</string>
<string name="keychain_is_storing_securely">Android Keystore%s parolayı güvenli bir şekilde saklamak için kullanılır - bildirim hizmetinin çalışmasını sağlar.</string>
<string name="button_welcome_message">Karşılama mesajı</string>
<string name="group_welcome_title">Karşılama mesajı</string>
<string name="voice_messages_are_prohibited">Sesli mesajlar yasaktır.</string>
@@ -25,7 +25,7 @@
<string name="app_passcode_replaced_with_self_destruct">Пароль застосунку замінено паролем самознищення.</string>
<string name="full_backup">Резервне копіювання даних застосунку</string>
<string name="smp_servers_add_to_another_device">Додати на інший пристрій</string>
<string name="keychain_is_storing_securely">Сховище ключів Android використовується для безпечного збереження ключової фрази - це дозволяє службі сповіщень працювати.</string>
<string name="keychain_is_storing_securely">Сховище ключів Android%s використовується для безпечного збереження ключової фрази - це дозволяє службі сповіщень працювати.</string>
<string name="v4_2_group_links_desc">Адміністратори можуть створювати посилання для приєднання до групи.</string>
<string name="app_version_code">Збірка додатку: %s</string>
<string name="allow_voice_messages_only_if">Дозволити голосові повідомлення тільки за умови, що ваш контакт дозволяє їх.</string>
@@ -82,7 +82,7 @@
<string name="connect_plan_already_joining_the_group">Đã tham gia nhóm rồi!</string>
<string name="always_use_relay">Luôn sử dụng relay</string>
<string name="rcv_group_and_other_events">và %d sự kiện khác</string>
<string name="keychain_is_storing_securely">Android Keystore được sử dụng để lưu trữ passphrase - nó cho phép dịch vụ thông báo hoạt động.</string>
<string name="keychain_is_storing_securely">Android Keystore%s được sử dụng để lưu trữ passphrase - nó cho phép dịch vụ thông báo hoạt động.</string>
<string name="keychain_allows_to_receive_ntfs">Android Keystore sẽ được sử dụng để lưu trữ passphrase một cách an toàn sau khi bạn khởi động lại ứng dụng hoặc thay đổi passphrase - nó cho phép tiếp nhận thông báo.</string>
<string name="migrate_from_device_all_data_will_be_uploaded">Tất cả các liên hệ, cuộc hội thoại và tệp của bạn sẽ được mã hóa an toàn và tải lên từng phần tới các XFTP relay được chỉ định.</string>
<string name="v5_6_safer_groups_descr">Quản trị viên có thể chặn một thành viên khỏi tất cả.</string>
@@ -89,7 +89,7 @@
<string name="users_delete_profile_for">为此删除聊天资料</string>
<string name="delete_database">删除数据库</string>
<string name="keychain_allows_to_receive_ntfs">在你重启应用程序或者更换密码后安卓密钥库系统用来安全地保存密码——来确保收到通知。</string>
<string name="keychain_is_storing_securely">安卓密钥库系统用来安全地保存密码——来确保通知服务运作。</string>
<string name="keychain_is_storing_securely">安卓密钥库系统%s用来安全地保存密码——来确保通知服务运作。</string>
<string name="appearance_settings">外观</string>
<string name="app_version_title">应用程序版本</string>
<string name="full_backup">应用程序数据备份</string>
@@ -94,7 +94,7 @@
<string name="full_backup">備份應用程式資料</string>
<string name="settings_section_title_icon">應用程式圖示</string>
<string name="chat_database_imported">已匯入對話資料庫</string>
<string name="keychain_is_storing_securely">Android 金鑰庫是用於安全地儲存密碼 - 確保通知推送服務的運作。</string>
<string name="keychain_is_storing_securely">Android 金鑰庫%s是用於安全地儲存密碼 - 確保通知推送服務的運作。</string>
<string name="impossible_to_recover_passphrase"><![CDATA[<b>請注意</b>:如果你忘記了密碼你將不能再次復原或修改密碼。]]></string>
<string name="keychain_allows_to_receive_ntfs">當你重新啟動應用程式或修改密碼後, Android 金鑰庫將用來安全地儲存密碼 - 將允許接收訊息通知。</string>
<string name="chat_is_stopped_indication">聊天已停止</string>
@@ -12,4 +12,6 @@ actual val cryptor: CryptorInterface = object : CryptorInterface {
override fun deleteKey(alias: String) {
// LALAL
}
override fun keyStorage(alias: String): String? = null
}
@@ -59,6 +59,7 @@ actual fun DatabaseEncryptionFooter(
useKeychain: MutableState<Boolean>,
chatDbEncrypted: Boolean?,
storedKey: MutableState<Boolean>,
keyStorage: String?,
initialRandomDBPassphrase: MutableState<Boolean>,
migration: Boolean,
) {