463 Stimmen

Bewährte Verfahren zum Speichern und Schützen privater API-Schlüssel in Anwendungen

Die meisten Entwickler von Anwendungen integrieren einige Bibliotheken von Drittanbietern in ihre Anwendungen. Sei es, um auf einen Dienst wie Dropbox oder YouTube zuzugreifen, oder um Abstürze zu protokollieren. Die Anzahl der Bibliotheken und Dienste von Drittanbietern ist atemberaubend. Die meisten dieser Bibliotheken und Dienste werden integriert, indem man sich auf irgendeine Weise beim Dienst authentifiziert, meistens geschieht dies über einen API-Schlüssel. Aus Sicherheitsgründen generieren die Dienste in der Regel einen öffentlichen und einen privaten, oft auch als geheim bezeichneten, Schlüssel. Leider muss dieser private Schlüssel zur Authentifizierung verwendet werden, um eine Verbindung zu den Diensten herzustellen, und ist daher wahrscheinlich Teil der Anwendung. Dies stellt natürlich ein großes Sicherheitsproblem dar. Öffentliche und private API-Schlüssel können innerhalb weniger Minuten aus APKs extrahiert werden und lassen sich leicht automatisieren.

Angenommen, ich habe etwas Ähnliches, wie kann ich den geheimen Schlüssel schützen?

public class DropboxService  {

    private final static String APP_KEY = "jk433g34hg3";
    private final static String APP_SECRET = "987dwdqwdqw90";
    private final static AccessType ACCESS_TYPE = AccessType.DROPBOX;

    // SOME MORE CODE HERE

}

Was ist Ihrer Meinung nach die beste und sicherste Art, den privaten Schlüssel zu speichern? Verschleierung, Verschlüsselung, was denken Sie?

410voto

Eric Lafortune Punkte 44044
  1. So wie es ist, enthält Ihre kompilierte Anwendung die Schlüsselstrings, aber auch die Konstantennamen APP_KEY und APP_SECRET. Das Extrahieren von Schlüsseln aus einem solchen selbstdokumentierenden Code ist trivial, zum Beispiel mit dem Android-Standardwerkzeug dx.

  2. Sie können ProGuard anwenden. Dabei bleiben die Schlüsselstrings unberührt, aber die Namen der Konstanten werden entfernt. Außerdem werden Klassen und Methoden in kurze, bedeutungslose Namen umbenannt, wo immer dies möglich ist. Das Extrahieren der Schlüssel nimmt dann etwas mehr Zeit in Anspruch, um herauszufinden, welche Zeichenfolge welchem Zweck dient.

    Beachten Sie, dass die Einrichtung von ProGuard nicht so schwierig sein sollte, wie Sie befürchten. Zu Beginn müssen Sie nur ProGuard aktivieren, wie in project.properties dokumentiert. Wenn es Probleme mit Bibliotheken von Drittanbietern gibt, müssen Sie möglicherweise einige Warnungen unterdrücken und/oder verhindern, dass sie in proguard-project.txt verschleiert werden. Zum Beispiel:

    -dontwarn com.dropbox.**
    -keep class com.dropbox.** { *; }

    Dies ist ein Brute-Force-Ansatz; Sie können diese Konfiguration verfeinern, sobald die verarbeitete Anwendung funktioniert.

  3. Sie können die Zeichenketten in Ihrem Code manuell verschleiern, z. B. mit einer Base64-Kodierung oder besser mit etwas Komplizierterem; vielleicht sogar mit nativem Code. Ein Hacker muss dann Ihre Kodierung statisch zurückentwickeln oder die Dekodierung an der richtigen Stelle dynamisch abfangen.

  4. Sie können einen kommerziellen Obfuskator, wie den spezialisierten Bruder von ProGuard, anwenden DexGuard . Es kann zusätzlich die Strings und Klassen für Sie verschlüsseln/verschleiern. Das Extrahieren der Schlüssel erfordert dann noch mehr Zeit und Fachwissen.

  5. Möglicherweise können Sie Teile Ihrer Anwendung auf Ihrem eigenen Server ausführen. Wenn Sie die Schlüssel dort aufbewahren können, sind sie sicher.

Letztendlich ist es ein wirtschaftlicher Kompromiss, den Sie eingehen müssen: Wie wichtig sind die Schlüssel, wie viel Zeit oder Software können Sie sich leisten, wie raffiniert sind die Hacker, die an den Schlüsseln interessiert sind, wie viel Zeit werden sie aufwenden wollen, wie viel ist eine Verzögerung wert, bevor die Schlüssel gehackt werden, in welchem Umfang werden erfolgreiche Hacker die Schlüssel verbreiten, usw. Kleine Informationseinheiten wie Schlüssel sind schwieriger zu schützen als ganze Anwendungen. An sich ist nichts auf der Client-Seite unknackbar, aber man kann die Messlatte durchaus höher legen.

(Ich bin der Entwickler von ProGuard und DexGuard)

94voto

marcinj Punkte 46621

Ein paar Ideen, wobei meiner Meinung nach nur die erste eine gewisse Garantie bietet:

  1. Bewahren Sie Ihre Geheimnisse auf einem Server im Internet auf, und bei Bedarf können Sie sie einfach abrufen und verwenden. Wenn ein Benutzer Dropbox verwenden möchte, dann hält Sie nichts davon ab, eine Anfrage an Ihre Website zu stellen und Ihren geheimen Schlüssel zu erhalten.

  2. Legen Sie Ihre Geheimnisse in jni-Code, fügen Sie einige variable Code, um Ihre Bibliotheken größer und schwieriger zu dekompilieren zu machen. Sie könnten auch den Schlüsselstring in mehrere Teile aufteilen und an verschiedenen Stellen aufbewahren.

  3. Obfuscator verwenden, auch in Code gehashte Geheimnis und später unhash es bei Bedarf zu verwenden.

  4. Fügen Sie Ihren geheimen Schlüssel als letztes Pixel eines Ihrer Bilder in die Assets ein. Lesen Sie ihn dann bei Bedarf in Ihrem Code ein. Die Verschleierung Ihres Codes sollte helfen, den Code zu verbergen, der ihn ausliest.

Wenn du einen schnellen Blick darauf werfen willst, wie einfach es ist, deinen apk-Code zu lesen, dann schnapp dir APKAnalyser:

http://developer.sonymobile.com/knowledge-base/tool-guides/analyse-your-apks-with-apkanalyser/

58voto

Skip Hovsmith Punkte 795

Eine andere Möglichkeit ist, das Geheimnis gar nicht erst auf dem Gerät zu haben! Siehe Mobile API-Sicherheitstechniken (insbesondere Teil 3).

Nutzen Sie die altehrwürdige Tradition der Umleitung, um das Geheimnis zwischen Ihrem API-Endpunkt und einem Anwendungsauthentifizierungsdienst auszutauschen.

Wenn Ihr Kunde einen Auftrag erteilen möchte API-Aufruf Er bittet den App-Authentifizierungsdienst, ihn zu authentifizieren (unter Verwendung starker Remote-Attestierungstechniken), und er erhält eine zeitlich begrenzte (normalerweise JWT ) Token mit der Unterschrift des Geheimnisses.

Das Token wird mit jedem API-Aufruf wo der Endpunkt seine Signatur überprüfen kann, bevor er die Anfrage bearbeitet.

Das eigentliche Geheimnis ist nie auf dem Gerät vorhanden; die App hat nie eine Ahnung, ob es gültig ist oder nicht, sie fordert lediglich eine Authentifizierung an und gibt das resultierende Token weiter. Ein netter Vorteil der Indirektion ist, dass Sie das Geheimnis ändern können, ohne dass die Benutzer ihre installierten Anwendungen aktualisieren müssen, falls Sie dies wünschen.

Wenn Sie also Ihr Geheimnis schützen wollen, ist es ein guter Weg, es gar nicht erst in Ihrer App zu haben.

35voto

SANAT Punkte 7703

Alter ungesicherter Weg:

Folgen Sie 3 einfachen Schritten, um den API/Geheimschlüssel zu sichern ( Alte Antwort )

Wir können Gradle verwenden, um den API-Schlüssel oder den geheimen Schlüssel zu sichern.

1. gradle.properties (Projekteigenschaften): Variable mit Schlüssel erstellen.

GoogleAPIKey = "Your API/Secret Key"

2. build.gradle (Modul: app) : Setzen Sie eine Variable in build.gradle, um in einer Aktivität oder einem Fragment darauf zuzugreifen. Fügen Sie den folgenden Code zu buildTypes {} hinzu.

buildTypes.each {
    it.buildConfigField 'String', 'GoogleSecAPIKEY', GoolgeAPIKey
}

3. Greifen Sie in Activity/Fragment über die BuildConfig der App darauf zu:

BuildConfig.GoogleSecAPIKEY

Aktualisierung:

Die obige Lösung ist hilfreich, um ein Open-Source-Projekt über Git zu übertragen. (Dank an David Rawson und riyaz-ali für Ihren Kommentar).

Wie in den Kommentaren von Matthew und Pablo Cegarra beschrieben, ist der obige Weg nicht sicher und Decompiler wird es jemandem ermöglichen, die BuildConfig mit unseren geheimen Schlüsseln einzusehen.

Lösung:

Wir können NDK verwenden, um API-Schlüssel zu sichern. Wir können Schlüssel in der nativen C/C++-Klasse speichern und in unseren Java-Klassen auf sie zugreifen.

Bitte folgen Sie este Blog zur Sicherung von API-Schlüsseln mit NDK.

Eine Folgefrage zur sicheren Speicherung von Token in Android

21voto

Ayman Al-Absi Punkte 2396

Ergänzend zur Lösung von @Manohar Reddy kann firebase Database oder firebase RemoteConfig (mit dem Standardwert Null) verwendet werden:

  1. Verschlüsseln Sie Ihre Schlüssel
  2. In der Firebase-Datenbank speichern
  3. Abruf beim Starten der App oder bei Bedarf
  4. Schlüssel entschlüsseln und verwenden

Was ist bei dieser Lösung anders?

  • keine Anmeldeinformationen für Firebase
  • Der Firebase-Zugang ist geschützt, so dass nur Anwendungen mit signiertem Zertifikat Zugang haben. das Privileg, API-Aufrufe zu tätigen
  • Verschlüsselung/Entschlüsselung, um das Abfangen durch Mittelsmänner zu verhindern. Allerdings ruft bereits https zu Firebase auf

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X