Verschlüsselte Einstellungen in Android

Guten Tag. Mein Name ist Dmitry und ich bin Lehrer des Grundkurses "Android Developer" in Otus. Heute habe ich beschlossen, die Übersetzung des Artikels zu teilen, was ich interessant finde und ich denke, dass es für viele Leser unseres Blogs nützlich sein kann.







Das Speichern von Daten in SharedPreferences ist sehr schnell und bequem. Es ist für Angreifer auch einfach, die in SharedPreferences gespeicherten Daten anzuzeigen. Seien Sie also vorsichtig, was Sie dort ablegen, und Sie müssen möglicherweise darüber nachdenken, wie die Daten in einem verschlüsselten Format gespeichert werden.

Für kleine Datenmengen, die die Verwendung eines Datenbankmoduls wie SqlCipher nicht rechtfertigen, waren unsere Funktionen begrenzt:

  • Native Verschlüsselungsmethoden (wenn Sie wissen, was Sie tun)
  • Fertige Lösungen wie sichere Einstellungen, andere sichere Einstellungen, Armadillo usw.
  • Bekämpfung der seltsamsten Probleme mit dem Keystore-Android-Systemlebenszyklus in jeder Android-Version

Das hat früher funktioniert, aber jetzt haben wir die richtige und offizielle Lösung .
Obwohl immer noch Alpha, hat es eine Weile gut funktioniert, als ich es in meinen Projekten verwendet habe. Die Verwendung von EncryptedSharedPreferences ist für alle mit min-sdk 23+ willkommen (oder Sie können es verwenden).

Schauen wir uns ein Beispiel für die Verwendung an:

Beispiel für EncryptedSharedPreferences


Minimales SDK


Heute 23 (Android 6.0)

minSdkVersion 23 

Abhängigkeiten hinzufügen


 implementation "androidx.security:security-crypto:1.0.0-alpha02" 

Initialisieren / Öffnen


Erstellen oder rufen Sie einfach den Hauptschlüssel aus dem Android-Keystore ab und initialisieren / öffnen Sie damit die EncryptedSharedPreferences-Instanz:

 //  1:    -   /  val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) //  2.  /   EncryptedSharedPreferences val sharedPreferences = EncryptedSharedPreferences.create( "PreferencesFilename", masterKeyAlias, applicationContext, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ) 

Datensätze speichern


Speichern Sie die Daten wie immer mit SharedPreferences:

 //  3.    EncryptedSharedPreferences sharedPreferences.edit() .putString("DATA", saveText.text.toString()) .apply() 


Notizen lesen


Lesen Sie die Daten wie immer mit SharedPreferences:
 //  3:    EncryptedSharedPreferences val value = sharedPreferences.getString("DATA", "") 

Sind die Einstellungen wirklich verschlüsselt?


Ja und wirklich ziemlich gut verschlüsselt.

akaita , ich habe den akaita Wert in SharedPreferences . So sieht die Datei aus:

 <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="DATA">akaita</string> </map> 

Wenn ich den akaita Wert zu EncryptedSharedPreferences hinzufüge, akaita ich etwas völlig anderes:

 <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="AVz2qCVxm1KudCCJKYuxuoaAXoPeWKjG0w==">ASnO9uni11t3m9sNgDJbiYllL/tE+i99TYKfQ0h8XV6AUN0O3rBxBsMmcpw2DCY=</string> <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a901eb372af4775b09f5b51d20d49428931c5d8e0b17dd103d2169c1879b8b13958274d7e25d3cc052f301461495fd40b70806ae244f456726802460318bdf19dce444e7a60f20c903c5a57140ea8e90a19a1b48559961d145a50000d1c0e22ca918b02ea0cc34e433900f44c00e9c791ecb678f26d293c0226d6c2a9e25e610616ec34241b06410481427a850eeedf85ee4c725d5dbd715b5a8d0e017be9a568a9f960989271d14d2d0531a4408a5d0dae705123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b6579100118a5d0dae7052001</string> <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">12880189e734bbbf9cfa3bc15b5e53ea8df03341269cf97112a60a1f6482732dd33248b3f821397fb04ef3372ff54336e9045a0b0c0fb7afdf475dbc98a1107d09de66afcc5ad063e5e5b59a7d616e14834e19769bc84de7e5c8716a811814a6cd7a6d72a1c64ce4317f2f482181c437b70f010219ca6407a98bac18f1101c02fd8e2c4a9009ad2a1ebbdc1a4408e9edbbce02123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b6579100118e9edbbce022001</string> </map> "> 12a901eb372af4775b09f5b51d20d49428931c5d8e0b17dd103d2169c1879b8b13958274d7e25d3cc052f301461495fd40b70806ae244f456726802460318bdf19dce444e7a60f20c903c5a57140ea8e90a19a1b48559961d145a50000d1c0e22ca918b02ea0cc34e433900f44c00e9c791ecb678f26d293c0226d6c2a9e25e610616ec34241b06410481427a850eeedf85ee4c725d5dbd715b5a8d0e017be9a568a9f960989271d14d2d0531a4408a5d0dae705123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b6579100118a5d0dae7052001 </ string> <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="AVz2qCVxm1KudCCJKYuxuoaAXoPeWKjG0w==">ASnO9uni11t3m9sNgDJbiYllL/tE+i99TYKfQ0h8XV6AUN0O3rBxBsMmcpw2DCY=</string> <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a901eb372af4775b09f5b51d20d49428931c5d8e0b17dd103d2169c1879b8b13958274d7e25d3cc052f301461495fd40b70806ae244f456726802460318bdf19dce444e7a60f20c903c5a57140ea8e90a19a1b48559961d145a50000d1c0e22ca918b02ea0cc34e433900f44c00e9c791ecb678f26d293c0226d6c2a9e25e610616ec34241b06410481427a850eeedf85ee4c725d5dbd715b5a8d0e017be9a568a9f960989271d14d2d0531a4408a5d0dae705123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b6579100118a5d0dae7052001</string> <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">12880189e734bbbf9cfa3bc15b5e53ea8df03341269cf97112a60a1f6482732dd33248b3f821397fb04ef3372ff54336e9045a0b0c0fb7afdf475dbc98a1107d09de66afcc5ad063e5e5b59a7d616e14834e19769bc84de7e5c8716a811814a6cd7a6d72a1c64ce4317f2f482181c437b70f010219ca6407a98bac18f1101c02fd8e2c4a9009ad2a1ebbdc1a4408e9edbbce02123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b6579100118e9edbbce022001</string> </map> "> 12880189e734bbbf9cfa3bc15b5e53ea8df03341269cf97112a60a1f6482732dd33248b3f821397fb04ef3372ff54336e9045a0b0c0fb7afdf475dbc98a1107d09de66afcc5ad063e5e5b59a7d616e14834e19769bc84de7e5c8716a811814a6cd7a6d72a1c64ce4317f2f482181c437b70f010219ca6407a98bac18f1101c02fd8e2c4a9009ad2a1ebbdc1a4408e9edbbce02123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b6579100118e9edbbce022001 </ string> <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="AVz2qCVxm1KudCCJKYuxuoaAXoPeWKjG0w==">ASnO9uni11t3m9sNgDJbiYllL/tE+i99TYKfQ0h8XV6AUN0O3rBxBsMmcpw2DCY=</string> <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a901eb372af4775b09f5b51d20d49428931c5d8e0b17dd103d2169c1879b8b13958274d7e25d3cc052f301461495fd40b70806ae244f456726802460318bdf19dce444e7a60f20c903c5a57140ea8e90a19a1b48559961d145a50000d1c0e22ca918b02ea0cc34e433900f44c00e9c791ecb678f26d293c0226d6c2a9e25e610616ec34241b06410481427a850eeedf85ee4c725d5dbd715b5a8d0e017be9a568a9f960989271d14d2d0531a4408a5d0dae705123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b6579100118a5d0dae7052001</string> <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">12880189e734bbbf9cfa3bc15b5e53ea8df03341269cf97112a60a1f6482732dd33248b3f821397fb04ef3372ff54336e9045a0b0c0fb7afdf475dbc98a1107d09de66afcc5ad063e5e5b59a7d616e14834e19769bc84de7e5c8716a811814a6cd7a6d72a1c64ce4317f2f482181c437b70f010219ca6407a98bac18f1101c02fd8e2c4a9009ad2a1ebbdc1a4408e9edbbce02123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b6579100118e9edbbce022001</string> </map> 

Darüber hinaus ändert sich die verschlüsselte Datei jedes Mal, wenn wir speichern, was den Zugriff erschwert.

Große Einschränkung: Leistung


Es gibt einen signifikanten Leistungsunterschied zwischen SharedPreferences und EncryptedSharedPreferences.

Sie können es selbst überprüfen, indem Sie meinen Beispielcode verwenden oder einfach die Beispielanwendung aus dem Play Store herunterladen. Ich selbst führe mehrere Tests an einem realen Gerät durch und erhalte die folgenden Ergebnisse:


EncryptedSharedPreferences vs. SharedPreferences


Grafik "EncryptedSharedPreferences versus SharedPreferences"

Fazit


EncryptedSharedPreferences ist eine zuverlässige und sehr einfache Lösung für Android 6.0 und höher.

Es hat zwei große Pluspunkte:

  1. Wir müssen nichts in unserem Code verschlüsseln. Er verwendet nur Android Keystore für uns, sodass wir uns nicht mehr darum kümmern müssen.
  2. Der Benutzer muss keinen Sperrbildschirm einstellen. EncryptedSharedPreferences funktioniert auch ohne Bildschirmsperre

Dies ist ein fast vollständiger Ersatz für SharedPreferences. Stellen Sie einfach sicher, dass das Initialisieren / Öffnen von EncryptedSharedPreferences Ihre Benutzer nicht beeinträchtigt.

Diese Entscheidung wird definitiv bleiben. Ich benutze dies in jedem geeigneten Szenario. Jetzt möchte ich nur sagen, dass die Jungs von Android ihre Leistung verbessern werden, damit wir uns noch weniger Sorgen machen können :)

Anwendungsbeispiel


Um das Testen zu vereinfachen und sicherzustellen, dass alles gut verbunden ist, habe ich eine Anwendung für Sie erstellt. Laden Sie es herunter oder kompilieren Sie es und probieren Sie es aus!

https://github.com/akaita/encryptedsharedpreferences-example

Setzen Sie ein Plus, wenn Sie den Artikel nützlich finden, und ich werde gerne alle Fragen in den Kommentaren beantworten.

Source: https://habr.com/ru/post/de473562/


All Articles