Kotlin‑Checkliste zur sicheren Speicherung von Tokens, Schlüsseln und PII
Checkliste zur sicheren Speicherung in Kotlin: Entscheidungshilfe zwischen Android Keystore, EncryptedSharedPreferences und Datenbankverschlüsselung für Tokens, Schlüssel und personenbezogene Daten.

Was du eigentlich schützen willst (in einfachen Worten)
Sichere Speicherung in einer Business‑App bedeutet eins: wenn jemand das Telefon (oder die App‑Dateien) in die Hand bekommt, sollte er trotzdem nicht lesen oder wiederverwenden können, was du gespeichert hast. Das betrifft Daten at rest (auf der Festplatte) und auch Geheimnisse, die über Backups, Logs, Crash‑Reports oder Debug‑Tools durchsickern.
Ein einfacher Gedankentest: Was könnte ein Fremder tun, wenn er deinen App‑Speicherordner öffnet? In vielen Apps sind die wertvollsten Dinge nicht Fotos oder Einstellungen, sondern kleine Strings, die Zugang freigeben.
Auf dem Gerät werden oft Session‑Tokens (damit Nutzer eingeloggt bleiben), Refresh‑Tokens, API‑Keys, Verschlüsselungsschlüssel, persönliche Daten (PII) wie Namen und E‑Mails und gecachte Geschäftsdaten für Offline‑Nutzung (Bestellungen, Tickets, Kundennotizen) gespeichert.
Hier sind typische reale Fehlerfälle:
- Ein verlorenes oder gestohlenes Gerät wird untersucht, und Tokens werden kopiert, um einen Nutzer zu impersonifizieren.
- Malware oder eine „Hilfs‑App“ liest lokale Dateien auf einem gerooteten Gerät oder per Accessibility‑Tricks.
- Automatische Geräte‑Backups verschieben deine App‑Daten an Orte, die du nicht geplant hast.
- Debug‑Builds loggen Tokens, schreiben sie in Crash‑Reports oder deaktivieren Sicherheitschecks.
Deshalb ist „speichere es einfach in SharedPreferences" keine akzeptable Lösung für alles, was Zugang gewährt (Tokens) oder Nutzern und Unternehmen schaden könnte (PII). Plain SharedPreferences ist wie ein Haftnotizzettel mit Geheimnissen in der App: praktisch, aber leicht lesbar, wenn jemand die Chance hat.
Der praktischste Anfang: nenne jedes gespeicherte Element und stell zwei Fragen: öffnet es etwas, und wäre es ein Problem, wenn es öffentlich würde? Daraus folgen Keystore, verschlüsselte Preferences oder verschlüsselte Datenbank.
Klassifiziere deine Daten: Tokens, Schlüssel und PII
Sichere Speicherung wird einfacher, wenn du aufhörst, alle „sensiblen Daten“ gleich zu behandeln. Listen zuerst auf, was die App speichert und was passieren würde, wenn es durchsickert.
Tokens sind nicht das Gleiche wie Passwörter. Access‑ und Refresh‑Tokens sollen so gespeichert werden, dass der Nutzer eingeloggt bleibt, sind aber trotzdem hochgradig wertvoll. Passwörter sollten gar nicht gespeichert werden. Wenn du Login brauchst, speichere nur, was nötig ist, um eine Session zu erhalten (meist Tokens) und überlasse Passwortprüfungen dem Server.
Schlüssel sind eine andere Klasse. API‑Keys, Signatur‑Keys und Verschlüsselungskeys können ganze Systeme öffnen, nicht nur ein Nutzerkonto. Wenn jemand sie vom Gerät extrahiert, kann er Missbrauch automatisieren. Gute Regel: wenn ein Wert außerhalb der App benutzt werden kann, um die App zu impersonifizieren oder Daten zu entschlüsseln, behandle ihn als risikoreicher als ein Nutzer‑Token.
PII sind alle Informationen, die eine Person identifizieren: E‑Mail, Telefon, Wohnadresse, Kundennotizen, Ausweisdaten, gesundheitsbezogene oder finanzielle Daten. Auch scheinbar harmlose Felder werden sensibel, sobald sie kombiniert werden.
Ein schnelles Labeling, das sich bewährt hat:
- Session‑Geheimnisse: Access‑Token, Refresh‑Token, Session‑Cookie
- App‑Geheimnisse: API‑Keys, Signatur‑Keys, Verschlüsselungsschlüssel (wenn möglich nicht auf Geräten ablegen)
- Nutzerdaten (PII): Profildaten, Identifikatoren, Dokumente, Gesundheits‑ oder Finanzdaten
- Geräte‑ und Analytics‑IDs: Advertising‑ID, Geräte‑ID, Install‑ID (unter vielen Richtlinien weiterhin sensibel)
Android Keystore: wann du ihn verwenden solltest
Android Keystore ist ideal, wenn du Geheimnisse schützen musst, die niemals in Klartext das Gerät verlassen dürfen. Er ist ein Tresor für kryptografische Schlüssel, nicht eine Datenbank für deine eigentlichen Daten.
Wofür er gut ist: Schlüssel zu generieren und zu verwahren, die zum Verschlüsseln, Entschlüsseln, Signieren oder Verifizieren benutzt werden. Meist verschlüsselst du ein Token oder Offline‑Daten anderswo, und ein Keystore‑Key schließt das Entschlüsseln auf.
Hardware‑gesicherte Schlüssel: was das wirklich bedeutet
Auf vielen Geräten können Keystore‑Schlüssel hardware‑gesichert sein. Das heißt, Schlüsseloperationen passieren in einer geschützten Umgebung und das Schlüsselmaterial lässt sich nicht extrahieren. Das senkt das Risiko durch Malware, die App‑Dateien lesen kann.
Hardware‑Backing ist nicht auf jedem Gerät garantiert, und das Verhalten variiert je nach Modell und Android‑Version. Baue so, als könnten Schlüsseloperationen fehlschlagen.
Benutzer‑Authentifizierungs‑Sperren
Keystore kann verlangen, dass vor der Nutzung eines Schlüssels der Nutzer bestätigt wird. So bindest du Zugriff an Biometrie oder Gerätepasswörter. Beispiel: du verschlüsselst ein Export‑Token und entschlüsselst es nur, nachdem der Nutzer per Fingerabdruck oder PIN bestätigt hat.
Keystore passt gut, wenn du einen nicht exportierbaren Schlüssel willst, Biometrie‑ oder Gerät‑Credential‑Zugriff für sensible Aktionen brauchst und wenn du gerätespezifische Geheimnisse willst, die nicht synchronisieren oder mit Backups mitreisen.
Plane für Fallstricke: Schlüssel können nach Änderungen am Sperrbildschirm, nach biometrischen Änderungen oder Sicherheitsereignissen invalidiert werden. Erwarten Fehler und implementiere einen sauberen Fallback: erkenne invalide Schlüssel, lösche verschlüsselte Blobs und fordere den Nutzer zur erneuten Anmeldung auf.
EncryptedSharedPreferences: wann es ausreicht
EncryptedSharedPreferences ist ein guter Default für eine kleine Menge von Geheimnissen im Key‑Value‑Format. Es ist „SharedPreferences, aber verschlüsselt“, sodass niemand einfach eine Datei öffnet und Werte liest.
Unter der Haube verwendet es einen Master‑Key, um Werte zu verschlüsseln und zu entschlüsseln. Dieser Master‑Key wird durch den Android Keystore geschützt, sodass deine App den Roh‑Verschlüsselungsschlüssel nicht im Klartext speichert.
Es reicht in der Regel für ein paar kleine Items, die häufig gelesen werden, wie Access‑ und Refresh‑Tokens, Session‑IDs, Geräte‑IDs, Environment‑Flags oder kleine Zustandswerte wie den letzten Sync‑Zeitpunkt. Es ist auch in Ordnung für winzige Teile von Nutzerdaten, wenn du sie wirklich speichern musst, aber es sollte nicht zur Ablagestelle für PII verkommen.
Es ist keine gute Wahl für große oder strukturierte Daten. Wenn du Offline‑Listen, Suche oder Abfragen nach Feldern brauchst (Kunden, Tickets, Bestellungen), wird EncryptedSharedPreferences langsam und unhandlich. Dann brauchst du eine verschlüsselte Datenbank.
Eine einfache Regel: wenn du alle gespeicherten Keys auf einem Bildschirm auflisten kannst, ist EncryptedSharedPreferences wahrscheinlich ausreichend. Wenn du Zeilen und Abfragen brauchst, wechsle weiter.
Datenbankverschlüsselung: wann du sie brauchst
Datenbankverschlüsselung ist wichtig, wenn du mehr als einen winzigen Wert speicherst. Wenn deine App Geschäftsdaten auf dem Gerät vorhält, geh davon aus, dass sie aus einem verlorenen Telefon extrahiert werden können, sofern du sie nicht schützt.
Eine Datenbank macht Sinn, wenn du Offline‑Zugriff auf Datensätze brauchst, lokales Caching für Performance, Historie/Audit‑Trails oder lange Notizen und Anhänge.
Zwei gängige Verschlüsselungsansätze
Vollständige Datenbankverschlüsselung (oft im Stil von SQLCipher) verschlüsselt die gesamte Datei at rest. Deine App öffnet sie mit einem Schlüssel. Das ist einfach zu überblicken, weil du nicht merken musst, welche Spalten geschützt sind.
Feld‑/App‑Layer‑Verschlüsselung verschlüsselt nur bestimmte Felder vor dem Schreiben und entschlüsselt nach dem Lesen. Das kann funktionieren, wenn die meisten Datensätze nicht sensibel sind oder du ein bestimmtes Datenbankformat beibehalten willst.
Tradeoffs: Vertraulichkeit vs. Suche und Sortierung
Volle Datenbankverschlüsselung versteckt alles auf der Festplatte, aber sobald die DB entsperrt ist, kann deine App normal abfragen.
Feldverschlüsselung schützt bestimmte Spalten, aber du verlierst einfache Suche und Sortierung auf verschlüsselten Werten. Nachname‑Sortierung auf verschlüsselten Werten funktioniert nicht zuverlässig, und Suche wird entweder „nach Entschlüsselung suchen“ (langsam) oder „zusätzliche Indizes speichern“ (komplizierter und potenziell undicht).
Grundlagen der Schlüsselverwaltung
Der Datenbank‑Schlüssel sollte niemals hardcodiert oder mit der App ausgeliefert werden. Ein gängiges Muster: generiere einen zufälligen DB‑Key und speichere ihn „wrapped“ (verschlüsselt) mit einem Key, der im Android Keystore liegt. Beim Logout kannst du den wrapped Key löschen und die lokale Datenbank als entbehrlich behandeln, oder sie behalten, wenn die App offline über Sessions hinweg funktionieren muss.
Wie man wählt: ein praktischer Vergleich
Du wählst nicht „die allgemein sicherste“ Option, sondern die sicherste Option, die zur Nutzung deiner App passt.
Fragen, die wirklich die richtige Wahl bestimmen:
- Wie oft werden die Daten gelesen (bei jedem Start oder selten)?
- Wie viel Daten sind es (ein paar Bytes oder tausende Datensätze)?
- Was passiert, wenn sie durchsickern (lästig, teuer, meldepflichtig)?
- Brauchst du Offline‑Zugriff, Suche oder Sortierung?
- Hast du Compliance‑Anforderungen (Aufbewahrung, Audit, Verschlüsselungsregeln)?
Eine praktikable Zuordnung:
- Tokens (OAuth Access und Refresh Tokens) gehören meist in
EncryptedSharedPreferences, weil sie klein sind und oft gelesen werden. - Schlüsselmaterial sollte wann immer möglich im Android Keystore leben, um die Chance zu verringern, dass es vom Gerät kopiert wird.
- PII und Offline‑Business‑Daten brauchen meist Datenbankverschlüsselung, sobald du mehr als ein paar Felder speicherst oder Offline‑Listen und Filter benötigst.
Gemischte Daten sind normal in Business‑Apps. Ein praktisches Muster: generiere einen zufälligen Data Encryption Key (DEK) für deine lokale Datenbank oder Dateien, speichere nur den wrapped DEK mit einem Keystore‑geschützten Schlüssel und rotiere ihn bei Bedarf.
Wenn du unsicher bist: wähle den simplen, sicheren Weg: speichere weniger. Vermeide Offline‑PII, wenn du es nicht wirklich brauchst, und halte Schlüssel im Keystore.
Schritt‑für‑Schritt: sichere Speicherung in einer Kotlin‑App implementieren
Beginne damit, alle Werte aufzuschreiben, die du auf dem Gerät speichern willst, und den genauen Grund, warum sie dort sein müssen. Das ist der schnellste Weg, „nur für den Fall“‑Speicherung zu verhindern.
Bevor du Code schreibst, lege Regeln fest: wie lange jedes Item lebt, wann es ersetzt wird und was „Logout“ genau bedeutet. Ein Access‑Token könnte in 15 Minuten ablaufen, ein Refresh‑Token länger, und Offline‑PII braucht vielleicht eine feste „nach 30 Tagen löschen“‑Regel.
Wartbarer Code‑Ansatz:
- Erstelle einen einzigen
SecureStorage‑Wrapper, damit der Rest der App nie direkt auf SharedPreferences, Keystore oder die DB zugreift. - Lege jedes Element am richtigen Ort ab: Tokens in
EncryptedSharedPreferences, Verschlüsselungskeys geschützt im Android Keystore und größere Offline‑Datensätze in einer verschlüsselten Datenbank. - Behandle Ausfälle bewusst. Wenn sichere Speicherung fehlschlägt, „fail closed“. Führe keinen stillen Fallback auf Klartextspeicherung durch.
- Füge Diagnosen hinzu, ohne Daten zu leaken: logge Ereignistypen und Fehlercodes, niemals Tokens, Keys oder Nutzerdetails.
- Verknüpfe Löschpfade: Logout, Kontoentfernung und „App‑Daten löschen“ sollten in dieselbe Wipe‑Routine laufen.
Teste die langweiligen Fälle, die sichere Speicherung in Produktion brechen: Wiederherstellung aus einem Backup, Upgrade von einer älteren App‑Version, Änderung der Gerätesperre, Migration auf ein neues Telefon. Sorge dafür, dass Nutzer nicht in einer Schleife landen, in der Daten nicht entschlüsselt werden können, die App aber immer wieder versucht.
Schreibe schließlich die Entscheidungen auf eine Seite, die das ganze Team versteht: was gespeichert wird, wo, Aufbewahrungsfristen und was passiert, wenn die Entschlüsselung fehlschlägt.
Häufige Fehler, die sichere Speicherung zerstören
Die meisten Fehlschläge sind nicht die falsche Bibliothek, sondern kleine Abkürzungen, die heimlich Geheimnisse an Orte kopieren, die du nicht meinst.
Das größte Warnsignal ist ein Refresh‑Token (oder langlebiges Session‑Token), das irgendwo im Klartext gespeichert wird: SharedPreferences, eine Datei, ein „temporärer“ Cache oder eine Datenbankspalte. Wenn jemand ein Backup, ein gerootetes Device‑Dump oder ein Debug‑Build‑Artefakt bekommt, kann dieses Token länger leben als das Passwort.
Geheimnisse leaken auch durch Sichtbarkeit, nicht nur durch Speicherung. Vollständige Request‑Header loggen, Tokens beim Debugging ausgeben oder hilfreiche Kontexte an Crash‑Reports und Analytics anhängen kann Credentials außerhalb des Geräts exponieren. Behandle Logs als öffentlich.
Key‑Handling ist eine weitere Lücke. Einen Schlüssel für alles zu verwenden vergrößert die Blast‑Radius. Nie Schlüsselrotation zu planen bedeutet, alte Kompromittierungen bleiben gültig. Schließe Key‑Versionierung, Rotation und das Verhalten alter verschlüsselter Daten in deine Planung ein.
Vergiss die „außerhalb des Tresors“‑Pfad nicht
Verschlüsselung stoppt nicht, dass Cloud‑Backups lokale App‑Daten kopieren. Sie stoppt Screenshots oder Screen‑Recording nicht, Debug‑Builds mit gelockerten Einstellungen nicht, oder Export‑Funktionen (CSV/Share) nicht, die sensible Felder abgeben können. Zwischenablage‑Nutzung kann ebenfalls Einmalcodes oder Kontonummern leaken.
Verschlüsselung behebt auch keine Autorisierungsfehler. Wenn deine App PII nach Logout anzeigt oder gecachte Daten ohne erneute Auth frei zugänglich bleiben, ist das ein Zugriffssteuerungsfehler. Sperre die UI, wipe sensible Caches beim Logout und prüfe Berechtigungen vor dem Anzeigen geschützter Daten.
Operative Details: Lebenszyklus, Logout und Randfälle
Sichere Speicherung ist nicht nur ein Ort, sondern wie Geheimnisse sich über die Zeit verhalten: wenn die App schläft, wenn ein Nutzer ausloggt und wenn das Gerät gesperrt ist.
Für Tokens plane den kompletten Lebenszyklus. Access‑Tokens sollten kurzlebig sein. Refresh‑Tokens sollten wie Passwörter behandelt werden. Wenn ein Token abläuft, erneuere ihn still im Hintergrund. Wenn ein Refresh fehlschlägt (revoked, Passwort geändert, Gerät entfernt), beende Wiederholschleifen und zwinge einen sauberen Sign‑In. Unterstütze auch serverseitige Widerrufe. Lokale Speicherung hilft nichts, wenn gestohlene Anmeldeinformationen nicht invalidiert werden.
Nutze Biometrie für Re‑Auth, nicht für alles. Frage bei Aktionen mit echtem Risiko (PII anzeigen, Daten exportieren, Auszahlung ändern, Einmal‑Keys anzeigen) nach Biometrie. Frage nicht bei jedem App‑Start.
Beim Logout sei streng und vorhersehbar:
- Leere zuerst In‑Memory‑Kopien (Tokens in Singletons, Interceptors oder ViewModels).
- Wische gespeicherte Tokens und Session‑Zustand (inkl. Refresh‑Tokens).
- Entferne oder invalidiere lokale Verschlüsselungskeys, wenn dein Design das vorsieht.
- Lösche Offline‑PII und gecachte API‑Antworten.
- Deaktiviere Hintergrundjobs, die Daten erneut abrufen könnten.
Randfälle zählen in Business‑Apps: mehrere Konten auf einem Gerät, Work‑Profiles, Backup/Restore, Geräte‑zu‑Geräte‑Transfer und partielle Logouts (Firma/Workspace wechseln statt komplettes Abmelden). Teste Force‑Stop, OS‑Upgrades und Zeitverschiebung, da Zeitdrift Ablauf‑Logik brechen kann.
Manipulationserkennung ist ein Tradeoff. Basischecks (debuggable Builds, Emulator‑Flags, einfache Root‑Signals, Play Integrity‑Urteile) reduzieren Gelegenheit für Missbrauch, aber entschlossene Angreifer umgehen sie. Behandle Tamper‑Signale als Risikofaktoren: begrenze Offline‑Zugriff, erfordere Re‑Auth und logge das Ereignis.
Schnelle Checkliste bevor du live gehst
Nutze das vor dem Release. Es zielt auf die Stellen, an denen sichere Speicherung in echten Business‑Apps versagt.
- Nimm an, das Gerät kann feindlich sein. Wenn ein Angreifer ein gerootetes Gerät oder ein komplettes Gerätabbild hat, können sie Tokens, Keys oder PII aus App‑Dateien, Preferences, Logs oder Screenshots lesen? Wenn die Antwort „vielleicht“ ist, verschiebe Geheimnisse in Keystore‑geschützte Bereiche und halte die Nutzlast verschlüsselt.
- Prüfe Backups und Geräte‑Transfers. Halte sensible Dateien aus Android Auto Backup, Cloud‑Backups und Geräte‑zu‑Geräte‑Transfer heraus. Wenn ein verlorener Key bei Restore die Entschlüsselung bricht, plane einen Recovery‑Flow (Re‑Auth und Neu‑Download statt zu versuchen, zu entschlüsseln).
- Suche nach versehentlichem Klartext auf Datenträgern. Checke Temp‑Files, HTTP‑Caches, Crash‑Reports, Analytics‑Events und Image‑Caches auf PII oder Tokens. Überprüfe Debug‑Logging und JSON‑Dumps.
- Ablauf und Rotation. Access‑Tokens kurzlebig, Refresh‑Tokens geschützt und serverseitig widerrufbar. Definiere Key‑Rotation und das Verhalten der App, wenn ein Token abgelehnt wird (löschen, re‑auth, einmaliges erneutes Versuchen).
- Verhalten bei Neuinstallation und Gerätewechsel. Teste Deinstallieren und Neuinstallieren, dann offline öffnen. Wenn Keystore‑Keys weg sind, sollte die App sicher fehlschlagen (verschlüsselte Daten löschen, Sign‑In anzeigen, partielle Leseversuche vermeiden).
Ein schneller Validierungstest ist der „schlechte Tag“: ein Nutzer loggt sich aus, ändert sein Passwort, stellt ein Backup auf ein neues Telefon wieder her und öffnet die App im Flugzeug. Das Ergebnis sollte vorhersehbar sein: entweder entschlüsseln sich die Daten für den richtigen Nutzer, oder sie werden gelöscht und nach Anmeldung neu geladen.
Beispiel‑Szenario: eine Business‑App, die PII offline speichert
Stell dir eine Außendienst‑App vor, die in Gebieten mit schlechtem Netz verwendet wird. Reps loggen sich morgens einmal ein, durchsuchen offline zugewiesene Kunden, fügen Meeting‑Notizen hinzu und synchronisieren später. Hier wird eine Speicher‑Checkliste praktisch und verhindert echte Lecks.
Eine praktische Aufteilung:
- Access‑Token: kurzlebig halten und in
EncryptedSharedPreferencesablegen. - Refresh‑Token: stärker schützen und Zugriff über Android Keystore absichern.
- Kunden‑PII (Namen, Telefon, Adressen): in einer verschlüsselten lokalen Datenbank speichern.
- Offline‑Notizen und Anhänge: in der verschlüsselten Datenbank speichern und bei Export/Sharing besonders vorsichtig sein.
Wenn du „Remember me“ hinzufügst, wird das Refresh‑Token zur Haupttür zurück ins Konto. Behandle es wie ein Passwort. Je nach Nutzerbasis könntest du vor dem Entschlüsseln eine Geräteentsperrung (PIN/Muster/Biometrie) verlangen.
Wenn du Offline‑Modus hinzufügst, schützt du nicht mehr nur eine Session, sondern eine komplette Kundenliste, die für sich wertvoll sein kann. Das schiebt dich meist in Richtung Datenbankverschlüsselung plus klare Logout‑Regeln: lokale PII löschen, nur das Nötigste für den nächsten Login behalten und Hintergrund‑Sync abbrechen.
Teste auf echten Geräten, nicht nur auf Emulatoren. Mindestens: Sperr/Entsperr‑Verhalten, Neuinstallation, Backup/Restore und Trennung zwischen mehreren Nutzern/Work‑Profiles prüfen.
Nächste Schritte: mache es zur Team‑Gewohnheit
Sichere Speicherung funktioniert nur, wenn sie Gewohnheit wird. Schreibe eine kurze Speicher‑Policy, die dein Team befolgt: was wo liegt (Keystore, EncryptedSharedPreferences, verschlüsselte DB), was niemals gespeichert wird und was beim Logout gelöscht werden muss.
Mache es Teil der täglichen Abläufe: Definition of Done, Code‑Reviews und Release‑Checks.
Eine leichte Reviewer‑Checkliste:
- Jedes gespeicherte Item ist gelabelt (Token, Schlüsselmaterial oder PII).
- Die Speicherentscheidung ist im Code kommentiert begründet.
- Logout und Kontowechsel entfernen die richtigen Daten (und nur diese Daten).
- Fehler und Logs drucken niemals Geheimnisse oder komplette PII.
- Jemand ist verantwortlich für die Policy und hält sie aktuell.
Wenn dein Team AppMaster (appmaster.io) verwendet, um Business‑Apps zu erstellen und Kotlin‑Quellcode für den Android‑Client zu exportieren, behalte denselben SecureStorage‑Wrapper‑Ansatz bei, sodass generierter und kundenspezifischer Code einer konsistenten Policy folgt.
Starte mit einem kleinen Proof‑of‑Concept
Baue ein kleines POC, das ein Auth‑Token und einen PII‑Datensatz speichert (z. B. eine Kunden‑Telefonnummer, die offline gebraucht wird). Teste Neuinstallation, Upgrade, Logout, Änderungen am Sperrbildschirm und „App‑Daten löschen“. Erweitere nur, wenn das Wipe‑Verhalten korrekt und reproduzierbar ist.
FAQ
Beginne damit, genau aufzuschreiben, was du speicherst und warum. Lege kleine Sitzungsgeheimnisse wie Access- und Refresh-Tokens in EncryptedSharedPreferences ab, sichere kryptografische Schlüssel im Android Keystore und verwende eine verschlüsselte Datenbank für Offline-Business-Daten und personenbezogene Daten (PII), sobald du mehr als ein paar Felder oder Abfragen brauchst.
Plain SharedPreferences legt Werte in einer Datei ab, die oft von Geräte-Backups, Zugriff auf gerootete Geräte oder Debug-Artefakte lesbar ist. Wenn der Wert ein Token oder PII ist, macht die Behandlung wie eine normale Einstellung es sehr einfach, ihn außerhalb der App zu kopieren und wiederzuverwenden.
Nutze Android Keystore, um kryptografische Schlüssel zu erzeugen und zu verwahren, die nicht extrahierbar sein sollen. Diese Schlüssel benutzt du in der Regel, um andere Daten zu verschlüsseln (Tokens, Datenbankschlüssel, Dateien) und kannst optional Benutzer‑Authentifizierung (Biometrie oder Gerätekredential) verlangen, bevor der Schlüssel verwendet wird.
Hardware‑Backing bedeutet, dass Schlüsseloperationen in geschützter Hardware stattfinden, sodass der Schlüsselmaterialien schwerer extrahierbar sind — selbst wenn ein Angreifer App‑Dateien lesen kann. Verlass dich nicht darauf, dass es auf jedem Gerät verfügbar ist oder sich immer gleich verhält; plane für Fehler und habe einen Recovery‑Flow, wenn Schlüssel nicht verfügbar oder invalidiert sind.
Für eine kleine Menge häufig gelesener Key‑Value‑Geheimnisse wie Access-/Refresh-Tokens, Session‑IDs und kleine Zustandswerte ist es meist ausreichend. Es ist nicht geeignet für große Datenmengen, strukturierte Offline‑Datensätze oder alles, was du durchsuchen und filtern musst, wie Kunden, Tickets oder Bestellungen.
Wähle eine verschlüsselte Datenbank, wenn du Offline‑Business‑Daten oder PII in größerem Umfang speicherst, Abfragen/Suchen/Sortieren brauchst oder Historien offline vorhalten willst. So verringerst du das Risiko, dass bei Verlust des Geräts komplette Kundenlisten oder Notizen exponiert werden, während die App weiter offline arbeitet — vorausgesetzt, die Schlüsselverwaltung ist sauber gelöst.
Volle Datenbankverschlüsselung schützt die gesamte Datei at rest und ist leichter nachzuvollziehen, weil du nicht mehr verfolgen musst, welche Spalten sensibel sind. Feldverschlüsselung kann für einzelne Spalten funktionieren, macht Suche und Sortierung aber kompliziert und erhöht das Risiko, durch Indizes oder abgeleitete Felder zu leaken.
Generiere einen zufälligen Datenbank‑Schlüssel und speichere ihn nur in „wrapped“ Form (verschlüsselt) mit einem Keystore‑geschützten Schlüssel. Hardcodierte Keys oder im App‑Bundle mitgelieferte Schlüssel sind tabu. Definiere außerdem, was beim Logout oder bei Key‑Invalidierung passiert (häufig: wrapped Key löschen und lokale Daten als vernachlässigbar betrachten).
Keys können durch Änderungen am Sperrbildschirm, biometrische Änderungen, OS‑Ereignisse oder Migration invalidiert werden. Erkenne Entschlüsselungsfehler explizit: wipe die verschlüsselten Blobs oder die lokale Datenbank sicher und fordere den Nutzer zur erneuten Anmeldung auf, anstatt in Schleifen zu geraten oder auf Klartext zurückzufallen.
Viele Lecks passieren „außerhalb des Tresors“: Logs, Crash‑Reports, Analytics‑Events, Debug‑Ausgaben, HTTP‑Caches, Screenshots, Clipboard‑Nutzung und Backup/Restore‑Pfade. Behandle Logs wie öffentlich, speichere niemals Tokens oder komplette PII, deaktiviere unbeabsichtigte Exportpfade und sorge dafür, dass Logout sowohl gespeicherte Daten als auch In‑Memory‑Kopien entfernt.


