Best Practice zum Speichern und Schützen privater API-Schlüssel in Anwendungen [geschlossen]

373

Die meisten App-Entwickler werden einige Bibliotheken von Drittanbietern in ihre Apps integrieren. Wenn Sie auf einen Dienst wie Dropbox oder YouTube zugreifen oder Abstürze protokollieren möchten. Die Anzahl der Bibliotheken und Dienste von Drittanbietern ist erschütternd. Die meisten dieser Bibliotheken und Dienste werden durch Authentifizierung beim Dienst integriert. Meistens geschieht dies über einen API-Schlüssel. Aus Sicherheitsgründen generieren Dienste normalerweise einen öffentlichen und privaten Schlüssel, der oft auch als geheimer Schlüssel bezeichnet wird. Leider muss dieser private Schlüssel zur Authentifizierung verwendet werden, um eine Verbindung zu den Diensten herzustellen, und daher wahrscheinlich Teil der Anwendung sein. Es ist unnötig zu erwähnen, dass dies mit einem immensen Sicherheitsproblem konfrontiert ist. Öffentliche und private API-Schlüssel können in wenigen Minuten aus APKs extrahiert und einfach automatisiert werden.

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 denkst du?

Grundcodierer
quelle
Ich hatte Speicher in Bild / PNG und bekomme Schlüssel durch PNG als BufferReader
Sumit
Ich denke, dass dies ein berechtigtes Anliegen ist und habe ein ähnliches Problem auf der Firebase Android SDK-Github-Seite veröffentlicht: github.com/firebase/firebase-android-sdk/issues/1583 . Mal sehen, ob das gehandhabt wird.
Grebulon

Antworten:

348
  1. So wie es ist, enthält Ihre kompilierte Anwendung die Schlüsselzeichenfolgen, aber auch die Konstantennamen APP_KEY und APP_SECRET. Das Extrahieren von Schlüsseln aus einem solchen selbstdokumentierenden Code ist beispielsweise mit dem Standard-Android-Tool dx trivial.

  2. Sie können ProGuard anwenden. Die Tastenketten bleiben unberührt, die konstanten Namen werden jedoch entfernt. Wo immer möglich, werden auch Klassen und Methoden mit kurzen, bedeutungslosen Namen umbenannt. Das Extrahieren der Schlüssel dauert dann etwas länger, um herauszufinden, welche Zeichenfolge welchem ​​Zweck dient.

    Beachten Sie, dass das Einrichten von ProGuard nicht so schwierig sein sollte, wie Sie befürchten. Zunächst 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 in proguard-project.txt unterdrücken und / oder verhindern, dass sie 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 Zeichenfolgen in Ihrem Code manuell verschleiern, z. B. mit einer Base64-Codierung oder vorzugsweise mit etwas Komplizierterem. vielleicht sogar nativer Code. Ein Hacker muss dann Ihre Codierung statisch rückentwickeln oder die Decodierung dynamisch an der richtigen Stelle abfangen.

  4. Sie können einen kommerziellen Verschleierer wie ProGuards spezialisiertes Geschwister DexGuard anwenden . Es kann zusätzlich die Zeichenfolgen 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.

Am Ende 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 hoch entwickelt sind die Hacker, die sich für die Schlüssel interessieren, wie viel Zeit werden sie wollen Geben Sie aus, wie viel Wert eine Verzögerung ist, bevor die Schlüssel gehackt werden, in welchem ​​Umfang erfolgreiche Hacker die Schlüssel verteilen usw. Kleine Informationen wie Schlüssel sind schwieriger zu schützen als ganze Anwendungen. Eigentlich ist nichts auf der Client-Seite unzerbrechlich, aber Sie können die Messlatte sicherlich höher legen.

(Ich bin der Entwickler von ProGuard und DexGuard)

Eric Lafortune
quelle
2
@EricLafortune macht es keinen Unterschied, ob die private Schlüsselzeichenfolge in der Java-Klasse oder in der String-Ressourcen-XML gespeichert ist?
Alan
1
@EricLafortune Ist es jetzt möglich, das Android Keystore-System zum sicheren Speichern der Schlüssel zu verwenden? ( developer.android.com/training/articles/keystore.html )
David Thomas
1
@ DavidThomas: Haben Sie versucht, Keystore zu verwenden. Ich möchte einen in der Java-Klasse geschriebenen API-Schlüssel verschleiern. Bitte antworten Sie
Sagar Trehan
1
Ist Android KeyStore dafür nützlich? ( developer.android.com/training/articles/… )
Weishi Zeng
1
Ich verstehe # 5 nicht. Hat es nicht genau die gleichen Probleme wie das ursprüngliche Problem?
Peter
80

Einige Ideen, meiner Meinung nach gibt nur die erste eine Garantie:

  1. Bewahren Sie Ihre Geheimnisse auf einem Server im Internet auf, und greifen Sie sie bei Bedarf einfach zu und verwenden Sie sie. Wenn der Benutzer Dropbox verwenden möchte, hindert Sie nichts daran, eine Anfrage an Ihre Site zu richten und Ihren geheimen Schlüssel zu erhalten.

  2. Legen Sie Ihre Geheimnisse in jni-Code, fügen Sie variablen Code hinzu, um Ihre Bibliotheken größer und schwieriger zu dekompilieren. Sie können die Tastenfolge auch in einige Teile teilen und an verschiedenen Stellen aufbewahren.

  3. Verwenden Sie den Obfuscator, geben Sie auch das Code-Hash-Geheimnis ein und lösen Sie es später bei Bedarf.

  4. Fügen Sie Ihren geheimen Schlüssel als letzte Pixel eines Ihrer Bilder in Assets ein. Lesen Sie es dann bei Bedarf in Ihrem Code. Das Verschleiern Ihres Codes sollte helfen, Code zu verbergen, der ihn liest.

Wenn Sie einen kurzen Blick darauf werfen möchten, wie einfach es ist, Ihren Apk-Code zu lesen, greifen Sie zu APKAnalyser:

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

marcinj
quelle
46
Wenn der Benutzer die App dekompilieren kann, obwohl er wahrscheinlich die Anforderung an Ihren eigenen Server ermitteln und diese einfach ausführen kann, um sie geheim zu halten. Keine Silberkugel hier, aber machen Sie ein paar Schritte und ich wette, es wird Ihnen gut gehen! Wenn Ihre App super beliebt ist, aber vielleicht auch nicht .. Tolle Ideen!
Matt Wolfe
3
Ja, Nummer 1 gibt keine Garantie.
März
42
Ich mag die Idee wirklich, Schlüssel in Bildern zu verstecken. +1
Igor Čordaš
1
@ MarcinJędrzejewski Möchten Sie mehr (vorzugsweise mit Beispiel- oder Snipped-Code) über die vierte Lösung erklären? Vielen Dank.
Dr.jacky
2
@ Mr.Hyde Dies nennt man Steganographie, es ist viel zu komplex, um hier einen Beispielcode anzugeben. Beispiele finden Sie auf Google. Ich habe hier eine gefunden: dreamincode.net/forums/topic/27950-steganography . Die Idee ist großartig, aber da apk-Code dekompiliert werden kann, verdirbt er seine Schönheit.
März
33

Ein anderer Ansatz ist, das Geheimnis überhaupt nicht auf dem Gerät zu haben! Siehe Mobile API-Sicherheitstechniken (insbesondere Teil 3).

Teilen Sie das Geheimnis zwischen Ihrem API-Endpunkt und einem App-Authentifizierungsdienst, indem Sie die altehrwürdige Tradition der Indirektion nutzen.

Wenn Ihr Client einen API-Aufruf tätigen möchte , fordert er den App-Authentifizierungsdienst auf, ihn zu authentifizieren (unter Verwendung starker Remote-Attestierungstechniken), und er erhält ein zeitlich begrenztes (normalerweise JWT ) Token, das vom Geheimnis signiert wird.

Das Token wird bei jedem API-Aufruf gesendet, bei dem der Endpunkt seine Signatur überprüfen kann, bevor er auf die Anforderung reagiert.

Das eigentliche Geheimnis ist auf dem Gerät niemals vorhanden. Tatsächlich hat die App keine Ahnung, ob sie gültig ist oder nicht. Sie fordert nur die Authentifizierung an und gibt das resultierende Token weiter. Wenn Sie das Geheimnis ändern möchten, können Sie dies als Vorteil der Indirektion tun, ohne dass Benutzer ihre installierten Apps aktualisieren müssen.

Wenn Sie also Ihr Geheimnis schützen möchten, ist es ein guter Weg, es nicht in Ihrer App zu haben.

Hovsmith überspringen
quelle
5
Dies sollte die akzeptierte Antwort sein.
Ortonomie
3
Das Problem besteht weiterhin, wenn Sie auf den Authentifizierungsdienst zugreifen möchten. Sie erhalten eine Kunden-ID und ein Kundengeheimnis. Wo sollen wir sie retten?
Ashi
Löst keine privaten APIs, bei denen Sie sich zuerst bei Ihrer API authentifizieren müssen, um sie verwenden zu können. Woher erhalten Sie die Anmeldeinformationen für alle App-Benutzer?
Kibotu
25

Alter ungesicherter Weg:

Befolgen Sie 3 einfache Schritte, um die API / den geheimen Schlü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.

GoolgeAPIKey = "Your API/Secret Key"

2. build.gradle (Modul: App): Legen Sie die Variable in build.gradle fest, um in Aktivität oder Fragment darauf zuzugreifen. Fügen Sie den folgenden Code zu buildTypes {} hinzu.

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

3. Greifen Sie in Aktivität / Fragment mit der BuildConfig der App darauf zu:

BuildConfig.GoogleSecAPIKEY

Update:

Die obige Lösung ist im Open Source-Projekt hilfreich, um ein Commit über Git durchzuführen. (Danke an David Rawson und Riyaz-Ali für Ihren Kommentar).

Laut den Kommentaren von Matthew und Pablo Cegarra ist der oben beschriebene Weg nicht sicher und Decompiler ermöglicht es jemandem, die BuildConfig mit unseren geheimen Schlüsseln anzuzeigen.

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 darauf zugreifen.

Bitte folgen Sie diesem Blog, um API-Schlüssel mit NDK zu sichern.

Ein Follow-up zum sicheren Speichern von Token in Android

SANAT
quelle
4
Das Speichern eines Schlüssels in einer Gradle-Datei ist sicher?
Google
4
@ Google gradle.propertiessollte nicht in Git eingecheckt werden, so ist dies eine Möglichkeit, das Geheimnis zumindest aus festgeschriebenem Quellcode herauszuhalten
David Rawson
4
Dies verhindert nicht, dass der API-Schlüssel in der resultierenden Datei gebündelt wird apk(er wird der generierten BuildConfigDatei hinzugefügt ), obwohl dies definitiv eine gute Idee ist, verschiedene API-Schlüssel zu verwalten (z. B. in einem Open Source-Projekt)
riyaz-ali
5
Die Verwendung eines Java-Dekompilers ermöglicht es jemandem, die BuildConfig-Datei und "GoogleSecAPIKEY"
Matthew
3
Ihre BuildConfig.javaDatei enthält den Schlüssel im Klartext. Dies ist nicht besser als das, was das OP bereits tut.
iceman
16

Der App-Secret-Schlüssel sollte privat bleiben - aber wenn die App veröffentlicht wird, können sie von einigen Leuten rückgängig gemacht werden.

Für diese Jungs wird es sich nicht verstecken, sperren Sie entweder ProGuardden Code. Es ist ein Refactor und einige bezahlte Verschleierer fügen einige bitweise Operatoren ein, um den jk433g34hg3 String zurückzugewinnen. Sie können das Hacken um 5 bis 15 Minuten verlängern, wenn Sie 3 Tage arbeiten :)

Der beste Weg ist, es so zu lassen, wie es ist, imho.

Selbst wenn Sie auf der Serverseite (Ihrem PC) speichern, kann der Schlüssel gehackt und ausgedruckt werden. Vielleicht dauert das am längsten? Jedenfalls ist es im besten Fall eine Frage von wenigen Minuten oder ein paar Stunden.

Ein normaler Benutzer wird Ihren Code nicht dekompilieren.


quelle
1
Nun - nicht die Antwort, auf die ich gehofft hatte =) ... Ich dachte, Sie können große Sicherheit erreichen :(
Basic Coder
Es tut uns leid, aber Sie wollten keine brillante, extrem sichere Lösung, aber für diejenigen, die den Compiler, den Dekompiler, verwenden können, gibt es keinen sicheren Java-Code: Selbst der native Code kann mit Hexa Viewer angezeigt und dektypisiert werden. Zumindest einen Versuch wert ...
1
Proguard wird den eigentlichen Schlüssel jedoch nicht verschleiern. Am besten ist eine einfache Encript / Decript-Routine, die sich verschleiert.
Doomsknight
3
es ist "sichtbar" die Entschlüsselungsroutine, ist einfach, das Gegenteil zu machen und Sie haben die ursprüngliche Zeichenfolge
14

Eine mögliche Lösung besteht darin, die Daten in Ihrer App zu codieren und zur Laufzeit zu dekodieren (wenn Sie diese Daten verwenden möchten). Ich empfehle außerdem, progaurd zu verwenden, um das Lesen und Verstehen des dekompilierten Quellcodes Ihrer App zu erschweren. Zum Beispiel habe ich einen verschlüsselten Schlüssel in die App eingefügt und dann eine Dekodierungsmethode in meiner App verwendet, um meine geheimen Schlüssel zur Laufzeit zu entschlüsseln:

// "the real string is: "mypassword" "; 
//encoded 2 times with an algorithm or you can encode with other algorithms too
public String getClientSecret() {
    return Utils.decode(Utils
            .decode("Ylhsd1lYTnpkMjl5WkE9PQ=="));
}

Der dekompilierte Quellcode einer bewachten App lautet wie folgt:

 public String c()
 {
    return com.myrpoject.mypackage.g.h.a(com.myrpoject.mypackage.g.h.a("Ylhsd1lYTnpkMjl5WkE9PQ=="));
  }

Zumindest ist es mir kompliziert genug. So mache ich das, wenn ich keine andere Wahl habe, als einen Wert in meiner Anwendung zu speichern. Natürlich wissen wir alle, dass es nicht der beste Weg ist, aber es funktioniert für mich.

/**
 * @param input
 * @return decoded string
 */
public static String decode(String input) {
    // Receiving side
    String text = "";
    try {
        byte[] data = Decoder.decode(input);
        text = new String(data, "UTF-8");
        return text;
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return "Error";
}

Dekompilierte Version:

 public static String a(String paramString)
  {
    try
    {
      str = new String(a.a(paramString), "UTF-8");
      return str;
    }
    catch (UnsupportedEncodingException localUnsupportedEncodingException)
    {
      while (true)
      {
        localUnsupportedEncodingException.printStackTrace();
        String str = "Error";
      }
    }
  }

und Sie können so viele Verschlüsselungsklassen mit einer kleinen Suche in Google finden.

Milad Faridnia
quelle
13

Zum Hinzufügen zur @ Manohar Reddy-Lösung können Firebase-Datenbank oder Firebase RemoteConfig (mit dem Standardwert Null) verwendet werden:

  1. Verschlüsseln Sie Ihre Schlüssel
  2. Speichern Sie es in der Firebase-Datenbank
  3. Holen Sie es sich beim Start der App oder wann immer erforderlich
  4. Schlüssel entschlüsseln und benutzen

Was ist bei dieser Lösung anders?

  • Keine Anmeldeinformationen für Firebase
  • Der Firebase-Zugriff ist geschützt, sodass nur Apps mit signiertem Zertifikat die Berechtigung haben, API-Aufrufe durchzuführen
  • Verschlüsselung / Entschlüsselung, um das Abfangen des Mittelmanns zu verhindern. Ruft jedoch bereits https an firebase auf
Ayman Al-Absi
quelle
Bei allem Respekt vor dieser Lösung sind wir immer noch das erste Quadrat. Anstatt Anmeldeinformationen zu verwenden, schlagen Sie vor, ein Zertifikat zu verwenden. Wer Ihre Anmeldeinformationen stehlen kann, kann Ihr signiertes Zertifikat stehlen.
Ashi
Ein Vorteil: Mit der vorgeschlagenen Lösung fügen wir dem Hacker eine weitere Komplikation hinzu.
Ashi
11

Dieses Beispiel hat verschiedene Aspekte. Ich werde einige Punkte erwähnen, von denen ich glaube, dass sie an keiner anderen Stelle ausdrücklich behandelt wurden.

Das Geheimnis auf der Durchreise schützen

Als Erstes müssen Sie für den Zugriff auf die Dropbox-API mithilfe des App-Authentifizierungsmechanismus Ihren Schlüssel und Ihr Geheimnis übertragen. Die Verbindung ist HTTPS, was bedeutet, dass Sie den Datenverkehr nicht abfangen können, ohne das TLS-Zertifikat zu kennen. Dies soll verhindern, dass eine Person die Pakete auf ihrer Reise vom mobilen Gerät zum Server abfängt und liest. Für normale Benutzer ist dies eine sehr gute Möglichkeit, die Privatsphäre ihres Datenverkehrs zu gewährleisten.

Was es nicht gut kann, ist zu verhindern, dass eine böswillige Person die App herunterlädt und den Datenverkehr überprüft. Es ist wirklich einfach, einen Man-in-the-Middle-Proxy für den gesamten Datenverkehr in und aus einem mobilen Gerät zu verwenden. Aufgrund der Art der Dropbox-API wäre in diesem Fall keine Demontage oder Rückentwicklung des Codes erforderlich, um den App-Schlüssel und das Geheimnis zu extrahieren.

Sie können eine Fixierung durchführen, bei der überprüft wird, ob das vom Server erhaltene TLS-Zertifikat das erwartete ist. Dies fügt dem Client eine Prüfung hinzu und erschwert das Abfangen des Datenverkehrs. Dies würde es schwieriger machen, den Verkehr im Flug zu inspizieren, aber die Pinning-Prüfung findet im Client statt, sodass es wahrscheinlich immer noch möglich wäre, den Pinning-Test zu deaktivieren. Es macht es allerdings schwieriger.

Das Geheimnis in Ruhe schützen

In einem ersten Schritt hilft die Verwendung von Proguard dabei, weniger deutlich zu machen, wo Geheimnisse verborgen sind. Sie können das NDK auch verwenden, um den Schlüssel und das Geheimnis zu speichern und Anfragen direkt zu senden, wodurch die Anzahl der Personen mit den entsprechenden Fähigkeiten zum Extrahieren der Informationen erheblich reduziert wird. Eine weitere Verschleierung kann erreicht werden, indem die Werte nicht für längere Zeit direkt im Speicher gespeichert werden. Sie können sie verschlüsseln und unmittelbar vor der Verwendung entschlüsseln, wie in einer anderen Antwort vorgeschlagen.

Erweiterte Optionen

Wenn Sie jetzt paranoid sind, das Geheimnis irgendwo in Ihrer App zu platzieren, und Zeit und Geld haben, um in umfassendere Lösungen zu investieren, können Sie die Anmeldeinformationen auf Ihren Servern speichern (vorausgesetzt, Sie haben welche). Dies würde die Latenz aller Aufrufe der API erhöhen, da diese über Ihren Server kommunizieren muss, und könnte die Kosten für die Ausführung Ihres Dienstes aufgrund des erhöhten Datendurchsatzes erhöhen.

Sie müssen dann entscheiden, wie Sie am besten mit Ihren Servern kommunizieren, um sicherzustellen, dass diese geschützt sind. Dies ist wichtig, um zu verhindern, dass dieselben Probleme mit Ihrer internen API erneut auftreten. Die beste Faustregel, die ich geben kann, ist, wegen der Bedrohung durch den Mann in der Mitte kein Geheimnis direkt zu übermitteln. Stattdessen können Sie den Datenverkehr mit Ihrem Geheimnis signieren und die Integrität aller an Ihren Server gesendeten Anforderungen überprüfen. Eine Standardmethode hierfür ist die Berechnung eines HMAC der Nachricht, die auf einem Geheimnis verschlüsselt ist. Ich arbeite in einem Unternehmen, das ein Sicherheitsprodukt hat, das auch in diesem Bereich tätig ist, weshalb mich solche Dinge interessieren. In der Tat ist hier ein Blog- Artikel von einem meiner Kollegen, der das meiste davon behandelt.

Wie viel soll ich tun?

Bei solchen Sicherheitsratschlägen müssen Sie eine Kosten-Nutzen-Entscheidung darüber treffen, wie schwer es für jemanden sein soll, einzudringen. Wenn Sie eine Bank sind, die Millionen von Kunden schützt, unterscheidet sich Ihr Budget völlig von dem, der eine App in ihrem Kunden unterstützt Freizeit. Es ist praktisch unmöglich zu verhindern, dass jemand Ihre Sicherheit verletzt, aber in der Praxis benötigen nur wenige Menschen alle Schnickschnack, und mit einigen grundlegenden Vorsichtsmaßnahmen können Sie einen langen Weg zurücklegen.

ThePragmatist
quelle
1
Sie haben dies einfach von hier kopiert und eingefügt: hackernoon.com/mobile-api-security-techniques-682a5da4fe10, ohne die Quelle anzugeben .
Ortonomie
1
@ortonomy Ich stimme zu, dass er den Artikel, den Sie verlinkt haben, hätte zitieren sollen, aber er hat ihn möglicherweise vergessen, weil beide am selben Ort arbeiten ...
Exadra37
2
Auch Skips Artikel und der Blog-Beitrag, auf dem sie basieren, kamen eine Woche nach meiner Antwort heraus.
ThePragmatist
8

Die sicherste Lösung besteht darin, Ihre Schlüssel auf einem Server zu belassen und alle Anforderungen, die diesen Schlüssel benötigen, über Ihren Server weiterzuleiten. Auf diese Weise verlässt der Schlüssel niemals Ihren Server. Solange Ihr Server sicher ist, gilt dies auch für Ihren Schlüssel. Natürlich verursacht diese Lösung Leistungskosten.

Bernard Igiri
quelle
32
Das Problem ist - um den Server zu erreichen, der alle Geheimnisse enthält, sollte ich einen anderen geheimen Schlüssel verwenden - ich frage mich, wo ich das aufbewahren werde? ;) Was ich versuche zu sagen ist - Dies ist auch nicht die beste Lösung (glaube nicht, dass es hier eine ideale Lösung gibt)
Merkur
Das stimmt nicht, Ihr Server ist vollständig unter Ihrer Kontrolle. Was es erfordert, liegt ganz bei Ihnen.
Bernard Igiri
5
Können Sie hier erklären, wie der Client die Daten verschlüsseln kann, die er an den Server senden möchte, während sich die Schlüssel auf der Serverseite befinden? und wenn Ihre Antwort lautet: - Der Server sendet Schlüssel an den Client. - Das muss also auch gesichert sein! also wieder keine magische lösung! Kannst du nicht sehen?!
Merkur
2
@BernardIgiri und dann sind wir wieder bei Quadrat 1. Nehmen wir an, das Telefon erstellt eine zufällige Anmeldung und der Server akzeptiert dies und sendet eine PIN (dies ist der sogenannte private Server, über den wir sprechen). Dann sieht die Person, die Ihre App zerlegt, dass für den Zugriff auf Ihren privaten Server nur eine zufällige Anmeldung erforderlich ist, die sie selbst erstellen kann. Sagen Sie mir, was ihn davon abhält, einen zu erstellen und auf Ihren Server zuzugreifen? Was ist der Unterschied zwischen Ihrer Lösung und dem Speichern eines Anmelde- oder API-Schlüssels auf dem Hauptserver (dessen Anmeldeinformationen wir auf unserem privaten Server speichern wollten)
Ken
3
@ken Die Zufallszahl wird anhand der Telefonnummer und des physischen Zugriffs auf ihre Textnachrichten authentifiziert. Wenn dich jemand betrügt, hast du seine Informationen. Wenn dies nicht gut genug ist, zwingen Sie sie, ein vollständiges Benutzerkonto und ein Kennwort zu erstellen. Wenn das nicht gut genug ist, besorgen Sie sich auch eine Kreditkarte. Wenn das nicht gut genug ist, rufen Sie sie an. Wenn das nicht gut genug ist, treffen Sie sie von Angesicht zu Angesicht. Wie sicher / unpraktisch möchten Sie sein?
Bernard Igiri
7

Halten Sie das Geheimnis in sich firebase databaseund erfahren Sie es, wenn die App startet. Es ist weitaus besser, als einen Webdienst anzurufen.

Manohar Reddy
quelle
13
aber was ist mit Anmeldeinformationen für Firebase?
the_joric
2
Leider funktioniert die Firebase-Datenbank in China nicht.
Konjengbam
9
macht keinen Sinn, Angreifer können sehen, dass Sie Firebase-Details aus dekompiliertem Code und alle Daten aus Ihrer Datenbank abrufen
user924
3
Ich denke, dies ist die beste Lösung, da Firebase Apps SHA1 verwenden, um den Zugriff auf den Server zu ermöglichen. Das Dekompilieren des Codes hilft nicht, Firebase aufzurufen, da die neue Hacker-App den genauen App-Stempel verwenden sollte, um auf Firebase zuzugreifen. Außerdem sollte der gespeicherte Schlüssel vor dem Speichern in der Firebase-Datenbank verschlüsselt und nach dem Empfang entschlüsselt werden, um ein Abfangen durch den Mittelsmann zu vermeiden.
Ayman Al-Absi
Wenn Sie das Geheimnis aus der Firebase-Datenbank über das Netzwerk erhalten, wie ist dies sicherer, als dasselbe Geheimnis von einem anderen Webdienst über einen sicheren (https) Kanal zu erhalten? Können Sie erklären?
Csaba Toth
6

Was auch immer Sie tun, um Ihre geheimen Schlüssel zu sichern, wird keine echte Lösung sein. Wenn Entwickler die Anwendung dekompilieren können, gibt es keine Möglichkeit, den Schlüssel zu sichern. Das Ausblenden des Schlüssels ist nur Sicherheit durch Dunkelheit, ebenso wie die Verschleierung des Codes. Das Problem beim Sichern eines geheimen Schlüssels besteht darin, dass Sie zum Sichern einen anderen Schlüssel verwenden müssen und dieser Schlüssel auch gesichert werden muss. Stellen Sie sich einen Schlüssel vor, der in einer Box versteckt ist, die mit einem Schlüssel verschlossen ist. Sie stellen eine Kiste in einen Raum und schließen den Raum ab. Sie müssen einen weiteren Schlüssel sichern. Und dieser Schlüssel wird immer noch in Ihrer Anwendung fest codiert.

Wenn der Benutzer keine PIN oder Phrase eingibt, kann der Schlüssel nicht ausgeblendet werden. Dazu müsste jedoch ein Schema für die Verwaltung von PINs außerhalb des Bandes vorhanden sein, dh über einen anderen Kanal. Sicherlich nicht praktisch zum Sichern von Schlüsseln für Dienste wie Google APIs.

user1611728
quelle
5

Alte alte Post, aber immer noch gut genug. Ich denke, es wäre großartig, es in einer .so-Bibliothek zu verstecken, natürlich mit NDK und C ++. .so-Dateien können in einem Hex-Editor angezeigt werden, aber viel Glück beim Dekompilieren von: P.

Ahmed Awad
quelle
9
Benutzer können problemlos Funktionsaufrufe an die gemeinsam genutzte Bibliothek senden und alles abrufen, was sich dort versteckt. Keine Notwendigkeit, es zu dekopieren.
David72
5
Laut androidauthority.com/… gibt es derzeit keinen sicheren Weg, dies in Android zu tun.
David72
1
@AhmedAwad Verstehe nicht, warum dies 3 Upvote hat. Jeder kann die App leicht dekompilieren und sehen, wie der ndk-Einstiegspunkt genannt wird: /
Johny19
1
Diese Antwort ist fast eine der besten Optionen, aber der Autor sollte erwähnen, dass es sehr wichtig ist, dass Sie einen Anruf (innerhalb Ihrer NDK-Bibliothek) einschließen, um festzustellen, ob die Prüfsumme mit Ihrer APK übereinstimmt, da sonst jemand Ihre NDK-Bibliothek außerhalb von anrufen kann Ihre App
Stoycho Andreev
@ Sniper das wäre toll, außer es hat ein großes Problem. Woher wissen Sie, welche Datei die native Methode "aufruft"? Wenn Sie den Namen der zu überprüfenden apk fest codieren, ist das großartig, aber was ist, wenn ich meine "hack" apk zum selben Ordner wie die "gute" apk mache? Es wird überprüft, ob die "gute" apk eine gute Prüfsumme hat, und es wird mir ermöglichen, diese native Methode auszuführen. Wenn es keine Möglichkeit gibt, die Anruferdatei von der JNI / C ++ - Seite zu kennen, ist dies wie die anderen Optionen sinnlos.
SocketByte
5

Der einzig wahre Weg, diese privat zu halten, besteht darin, sie auf Ihrem Server zu belassen und die App alles an den Server senden zu lassen, und der Server interagiert mit Dropbox. Auf diese Weise verteilen Sie Ihren privaten Schlüssel NIEMALS in einem beliebigen Format.

Nick
quelle
11
Aber wie verhindern Sie, dass der Rest der Welt den Server anruft?
user2966445
Wenn Sie mit "dem Server" Ihren Webserver meinen, auf dem sich die Anmeldeinformationen befinden, können Sie eine beliebige Methode verwenden. einfache Authentifizierung mit Benutzername / Passwort, oauth, Active Directory usw. usw. Hängt wirklich von Ihrer Anwendung ab.
Nick
Vielleicht fehlt mir etwas, aber erfordert dies nicht das Speichern von Anmeldeinformationen in der App?
user2966445
3
Richtig, aber Sie sagten, die App würde sich zuerst beim Server authentifizieren. Bedeutet dies nicht, dass weitere Anmeldeinformationen in der App gespeichert werden? Ich verstehe, dass der Server die eigentlichen Dropbox-Anrufe verarbeiten würde.
user2966445
4
Nun, das könnte bedeuten, aber es ist eine völlig separate Autorisierung. Aber das musst du nicht. Der Anwendungsfall, über den ich spreche, ist, dass Ihr App-Benutzer sich bei Ihrer App anmelden würde, beispielsweise über Facebook oder Twitter. Sie speichern ihre Anmeldeinformationen nicht in Ihrer App, Sie kennen sie nicht einmal. Dieser Autorisierungsprozess ermöglicht ihnen den Zugriff auf Ihren API-Server, der über die Anmeldeinformationen für Dropbox verfügt, auf den jedoch keine App oder kein Benutzer direkt zugreifen kann.
Nick
0

Basierend auf bitteren Erfahrungen und nach Rücksprache mit einem IDA-Pro-Experten besteht die beste Lösung darin, einen wichtigen Teil des Codes in eine DLL / SharedObject zu verschieben, ihn dann von einem Server abzurufen und zur Laufzeit zu laden.

Sensible Daten müssen verschlüsselt werden, da dies sehr einfach ist:

$ strings libsecretlib.so | grep My
  My_S3cr3t_P@$$W0rD
RonTLV
quelle
3
Und wo speichern Sie die Anmeldeinformationen für diesen Server?
ZX9