Wie speichere ich Zugriffstoken und Geheimnisse sicher in Android?

123

Ich werde oAuth verwenden, um Mails und Kontakte von Google abzurufen. Ich möchte den Benutzer nicht jedes Mal bitten, sich anzumelden, um ein Zugriffstoken und ein Geheimnis zu erhalten. Soweit ich verstanden habe, muss ich sie mit meiner Anwendung entweder in einer Datenbank oder in einer Datenbank speichern SharedPreferences. Aber ich mache mir ein bisschen Sorgen um Sicherheitsaspekte. Ich habe gelesen, dass Sie die Token verschlüsseln und entschlüsseln können, aber es ist für einen Angreifer einfach, nur Ihre apk und Klassen zu dekompilieren und den Verschlüsselungsschlüssel zu erhalten.
Was ist die beste Methode, um diese Token sicher in Android zu speichern?

Ja Mann
quelle
1
Wie speichere ich den Consumer-Schlüssel und das Geheimnis (die Hardconding-Funktion ist nicht gesichert)? Ich brauche sie, um den Zugang und das Geheimnis anzufordern. Wie machen es die anderen vorhandenen Apps, die oauth verwenden? hmm endlich mit oauth, du musst dich um viel mehr sicherheitsprobleme für mich kümmern .... ich muss das verbraucher-token / geheim geheim halten und auch das accesstoken und geheim .... endlich wäre es nicht einfacher zu Speichern Sie einfach den Benutzernamen / das Passwort des Benutzers verschlüsselt? ... ist letzteres nicht besser? Ich kann immer noch nicht sehen, wie besser es ist ...
yeahman
Kannst du mir sagen, in welcher Datei das Zugriffstoken gespeichert ist? Ich bin neu in Android und ich habe versucht, Probe Plus App auszuführen. Aber ich finde diese nirgendwo [GoogleAuthUtil.getToken () Methode.]
Abhishek Kaushik

Antworten:

118

Speichern Sie sie als gemeinsame Einstellungen . Diese sind standardmäßig privat und andere Apps können nicht darauf zugreifen. Wenn der Benutzer auf gerooteten Geräten explizit den Zugriff auf eine App zulässt, die versucht, sie zu lesen, kann die App sie möglicherweise verwenden, aber Sie können sich nicht davor schützen. Bei der Verschlüsselung muss der Benutzer entweder jedes Mal die Entschlüsselungspassphrase eingeben (wodurch der Zweck des Zwischenspeicherns von Anmeldeinformationen zunichte gemacht wird) oder den Schlüssel in einer Datei speichern, und es tritt das gleiche Problem auf.

Es gibt einige Vorteile beim Speichern von Token anstelle des tatsächlichen Benutzernamen-Passworts:

  • Apps von Drittanbietern müssen das Kennwort nicht kennen und der Benutzer kann sicher sein, dass er es nur an die ursprüngliche Website (Facebook, Twitter, Gmail usw.) sendet.
  • Selbst wenn jemand ein Token stiehlt, kann er das Passwort nicht sehen (das der Benutzer möglicherweise auch auf anderen Websites verwendet).
  • Token haben in der Regel eine Lebensdauer und verfallen nach einer bestimmten Zeit
  • Token können widerrufen werden, wenn Sie den Verdacht haben, dass sie kompromittiert wurden
Nikolay Elenkov
quelle
1
Danke für die Antwort! Aber wie kann ich feststellen, ob mein Consumer-Schlüssel kompromittiert wurde? lol es wird schwer zu sagen sein .. ok über das Speichern des Zugriffstokens und des Geheimnisses, ok ich speichere sie in gemeinsamen Einstellungen und verschlüssele sie, aber wie wäre es mit Consumer Key und Secret? Ich kann sie nicht in gemeinsam genutzten Einstellungen speichern (ich müsste den Consumer-Schlüssel und das Geheimnis explizit in den Code schreiben, um ihn überhaupt in gemeinsam genutzten Einstellungen zu speichern). Ich weiß nicht, ob Sie verstehen, was ich meine.
Yeahman
2
Sie müssen die App entweder (etwas) verschleiert in die App einfügen, damit sie nach der Dekompilierung nicht sofort sichtbar ist, oder Sie verwenden Ihre eigene Authrorization-Proxy-Webanwendung, die den Schlüssel und das Geheimnis enthält. Das Einfügen in die App ist offensichtlich einfacher. Wenn das Risiko besteht, dass jemand versucht, Ihre App zu knacken, ist dieser Ansatz ausreichend. Übrigens gelten die obigen Punkte für das Benutzerpasswort. Wenn Sie herausfinden, dass Ihr Verbraucherschlüssel / -geheimnis kompromittiert wurde, können Sie diese auch widerrufen (dies wird Ihre App natürlich beschädigen).
Nikolay Elenkov
1
@NikolayElenkov: Sie haben geschrieben: "Bei der Verschlüsselung muss der Benutzer entweder jedes Mal die Entschlüsselungspassphrase eingeben (wodurch der Zweck des Zwischenspeicherns von Anmeldeinformationen zunichte gemacht wird) oder den Schlüssel in einer Datei speichern, und Sie erhalten das gleiche Problem." . Was ist, wenn Cracker Ihre App umkehren, um zu erfahren, wie die Verschlüsselung funktioniert? Ihre Verteidigung kann gebrochen sein. Ist es eine bewährte Methode, solche Informationen (Token, Verschlüsselung ...) mit nativem Code zu speichern?
anhldbk
1
Wenn App-Daten gelöscht werden, geht das Aktualisierungstoken verloren, was wahrscheinlich nicht das ist, was der Benutzer wollte.
rds
1
Dies ist nicht mehr der beste Weg, um Token zu speichern!
Rahul Rastogi
19

Sie können sie im AccountManager speichern . Diesen Jungs zufolge gilt es als Best Practice.

Geben Sie hier die Bildbeschreibung ein

Hier ist die offizielle Definition:

Diese Klasse bietet Zugriff auf eine zentralisierte Registrierung der Online-Konten des Benutzers. Der Benutzer gibt einmal pro Konto Anmeldeinformationen (Benutzername und Kennwort) ein und gewährt Anwendungen mit "Ein-Klick" -Zulassung Zugriff auf Online-Ressourcen.

Ausführliche Informationen zur Verwendung von AccountManager:

Am Ende speichert AccountManager Ihr Token jedoch nur als einfachen Text. Daher würde ich vorschlagen, Ihr Geheimnis zu verschlüsseln, bevor Sie es in AccountManager speichern. Sie können verschiedene Verschlüsselungsbibliotheken wie AESCrypt oder AESCrypto verwenden

Eine weitere Option ist die Verwendung der Conceal-Bibliothek . Es ist sicher genug für Facebook und viel einfacher zu bedienen als AccountManager. Hier ist ein Code-Snippet zum Speichern einer geheimen Datei mit Conceal.

byte[] cipherText = crypto.encrypt(plainText);
byte[] plainText = crypto.decrypt(cipherText);
Aldok
quelle
2
Guter Tipp, der verbirgt. Sieht sehr einfach zu bedienen. Und für viele Anwendungsfälle.
Lagos
Conceal konnte über den Link nicht gefunden werden. Es kann deaktiviert werden
user1114
9

SharedPreferences ist selbst kein sicherer Speicherort. Auf einem gerooteten Gerät können wir die SharedPrefereces-XML-Dateien aller Anwendungen problemlos lesen und ändern. Token sollten daher relativ häufig ablaufen. Aber selbst wenn ein Token jede Stunde abläuft, können neuere Token aus SharedPreferences gestohlen werden. Android KeyStore sollte zum langfristigen Speichern und Abrufen von kryptografischen Schlüsseln verwendet werden, mit denen unsere Token verschlüsselt werden, um sie beispielsweise in SharedPreferences oder einer Datenbank zu speichern. Die Schlüssel werden nicht im Prozess einer Anwendung gespeichert, sodass sie schwerer zu kompromittieren sind.

Relevanter als ein Ort ist also, wie sie selbst sicher sein können, z. B. mithilfe kryptografisch signierter kurzlebiger JWTs, Verschlüsselung mit Android KeyStore und Senden mit einem sicheren Protokoll

apex39
quelle
9
Wo können wir sie dann aufbewahren?
Milind Mevada
3
  1. Wählen Sie im Projektbereich Ihres Android Studios "Projektdateien" aus und erstellen Sie eine neue Datei mit dem Namen "keystore.properties" im Stammverzeichnis Ihres Projekts.

Geben Sie hier die Bildbeschreibung ein

  1. Öffnen Sie die Datei "keystore.properties" und speichern Sie Ihr Zugriffstoken und Ihr Geheimnis in der Datei.

Geben Sie hier die Bildbeschreibung ein

  1. Laden Sie nun das Read the Access Token und Secret in die build.gradle- Datei Ihres App- Moduls . Anschließend müssen Sie die BuildConfig-Variable für Ihr Zugriffstoken und Ihr Geheimnis definieren, damit Sie direkt von Ihrem Code aus darauf zugreifen können. Ihr build.gradle sieht möglicherweise folgendermaßen aus:

    ... ... ... 
    
    android {
        compileSdkVersion 26
    
        // Load values from keystore.properties file
        def keystorePropertiesFile = rootProject.file("keystore.properties")
        def keystoreProperties = new Properties()
        keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
        defaultConfig {
            applicationId "com.yourdomain.appname"
            minSdkVersion 16
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
            // Create BuildConfig variables
            buildConfigField "String", "ACCESS_TOKEN", keystoreProperties["ACCESS_TOKEN"]
            buildConfigField "String", "SECRET", keystoreProperties["SECRET"]
        }
    }
  2. Sie können Ihr Zugriffstoken und Ihr Geheimnis in Ihrem Code folgendermaßen verwenden:

    String accessToken = BuildConfig.ACCESS_TOKEN;
    String secret = BuildConfig.SECRET;

Auf diese Weise müssen Sie das Zugriffstoken und das Geheimnis nicht im Klartext in Ihrem Projekt speichern. Selbst wenn jemand Ihre APK dekompiliert, erhält er niemals Ihr Zugriffstoken und Ihr Geheimnis, wenn Sie sie aus einer externen Datei laden.

Zahidur Rahman Faisal
quelle
1
Es scheint keinen Unterschied zu geben, dass beim Erstellen einer Eigenschaftendatei stattdessen eine harte Codierung erstellt wird.
Dzshean
Ich möchte Token zur Laufzeit schreiben, möglicherweise wird mein Token jedes Mal geändert, wenn ich meine App öffne.
Rehan Sarwar
1
Es ist eine sehr gute Möglichkeit, einige Token wie API-Zugriffstoken zu speichern. Wenn Sie Benutzeranmeldeinformationen speichern möchten, ist das NDK eine bessere Möglichkeit.
Eric
6
Auf diese Weise sollten Sie keine vertraulichen Informationen in Ihrer Anwendung speichern! Selbst wenn das Repository die Daten mit diesem Ansatz nicht enthält (die Daten werden in den Erstellungsprozess eingefügt), wird eine BuildConfig-Datei generiert, die das Token / Geheimnis im Klartext enthält, damit alle es nach einer einfachen Dekompilierung sehen können.
Hrafn
-1

Nun, Sie können Ihren Zugriffstoken sichern, indem Sie zwei Optionen folgen.

  1. Verwenden Sie Speichern Sie Ihr Zugriffstoken in Android Keystore, die nicht umgekehrt wäre.
  2. Verwenden Sie die NDK-Funktion mit einigen Berechnungen, die Ihr Token und NDK mit C ++ - Code speichern, der nur sehr schwer rückgängig zu machen ist
M.Noman
quelle