it-swarm-eu.dev

Ist es in Ordnung, dass API-Geheimnisse im Klartext gespeichert oder entschlüsselt werden können?

Sind nicht API keys berücksichtigte Benutzernamen und API secrets Passwörter berücksichtigt? Warum können Sie mit API-Servern wie Amazon Web Services Ihr API-Geheimnis im Klartext anzeigen? Ich denke, sie speichern es im Klartext oder zumindest in einem entschlüsselbaren Format.

Ist es nicht besser, wenn API-Geheimnisse als Kennwörter behandelt wurden, die Sie eingeben sollten, um sie zu erstellen, und dann in der Datenbank gehasht werden, anstatt sie im Klartext zu erhalten? Wenn aus irgendeinem Grund die geheime API-Datenbank kompromittiert wurde, werden die Schleusen für viele Anwendungen, die ihre API verwenden, leicht geöffnet. Wenn es jedoch auf nicht entschlüsselbare Weise gehasht wurde, ist nicht alles leicht verloren.

36
IMB

Nein. Die API-Schlüssel müssen im Klartext gespeichert werden.

Sie sind keine Passwörter, sondern kryptografische Schlüssel. Diese Schlüssel werden beispielsweise zur Authentifizierung von Anforderungen (mithilfe von SHA1-HMAC) verwendet. Der Server muss den Kryptoschlüssel kennen, um die kryptografischen Algorithmen anwenden zu können.

Daher muss der API-Schlüssel im Klartext auf dem Server gespeichert werden. Wenn der Server nur einen Hash des API-Schlüssels gespeichert hat, konnte er die Authentizität von Nachrichten vom Client nicht überprüfen oder an den Client gesendete Nachrichten nicht authentifizieren.

17
D.W.

Hashing ist keine Lagerung; es zerstört irreversibel Daten. Wir können mit dem Aufrufen von Passwort-Hashing als "Passwortspeicher" davonkommen, denn wenn wir das Passwort tatsächlich benötigen, haben wir einen praktischen menschlichen Operator, der es eingibt. Wenn wir das Passwort hashen, speichern wir das Passwort nicht, sondern nur ein Token ausreichend, um das eingegebene Passwort zu überprüfen.

Ein API-Schlüssel muss so gespeichert werden, dass er unbeaufsichtigt wieder verwendet werden kann. Der Server muss es wirklich speichern, anstatt sich nur an einen Geist zu erinnern, da er den echten Schlüssel benötigt, um auf die API zuzugreifen.

13
Tom Leek

Das Hashing der API-Token wäre zwar sicherer, stellt jedoch ein Usability-Problem dar: Die Token sind lang und zufällig und müssten dem Benutzer vor dem Hashing nur einmal mitgeteilt werden. Dies macht es ein wenig schwierig, sie mit einem Hash zu sichern.

Mein Vorschlag für ein sicheres Szenario wäre folgender:

  1. Generieren Sie einen zufälligen salt -Wert und speichern Sie ihn in der Datenbank. Dieses Salt darf nicht mit dem Passwort des Benutzers Salt übereinstimmen.
  2. Nehmen Sie das Klartextkennwort des Benutzers und berechnen Sie KDF(password, salt), wobei KDF eine Schlüsselableitungsfunktion wie bcrypt ist. Rufen Sie den resultierenden Wert k auf.
  3. Generieren Sie einen API-Schlüssel.
  4. Verschlüsseln Sie den API-Schlüsselwert mit AES unter Verwendung von k als Schlüssel und speichern Sie den Chiffretext in der Datenbank.
  5. Verwerfen Sie den Klartext-API-Schlüssel und k.

Wenn sich der Benutzer anmeldet, kennt die Webanwendung ihr Kennwort und berechnet daraus k, mit dem der API-Schlüssel entschlüsselt und angezeigt wird.

Wenn der Benutzer die API verwenden möchte, muss er k sowie den Klartext-API-Schlüssel über SSL senden. Die Webanwendung kann dann den gespeicherten API-Schlüsselwert mit k entschlüsseln und mit dem angegebenen API-Schlüssel vergleichen. Wenn sie übereinstimmen, ist es gültig. Dies ermöglicht die Verwendung von API-Schlüsseln, ohne dass die App das Kennwort des Benutzers speichern muss.

Wenn ein Angreifer die Datenbank verletzt, muss er das Kennwort des Benutzers knacken, um k zu berechnen.

9
Polynomial

Hier scheint es ein bisschen Verwirrung zu geben und an anderen Stellen , also füge ich diese Antwort in der Hoffnung hinzu, dass sie die Situation für andere Benutzer klären wird.

Es gibt zwei Arten von API-Geheimnissen, die verwendet werden können.

Der Anwendungsfall, den die meisten Antworten auf dieser Seite diskutieren, ist ein geheimer Schlüssel, der zum Signieren und Überprüfen von Nachrichten mithilfe eines Algorithmus wie HMAC verwendet wird. In diesem Fall benötigen sowohl der Client als auch die API den tatsächlichen Wert des Schlüssels, um eine Signatur der Nachricht zu erstellen. Der Server vergleicht dann die von ihm generierte Signatur mit der vom Client gesendeten Signatur und kann die Nachricht überprüfen. Wie oben erwähnt, kann dies nicht funktionieren, wenn der Originalschlüssel auf dem Server nicht reproduzierbar ist. Nach dem erstmaligen Teilen des Schlüssels mit dem Client (über einen verschlüsselten Kanal) muss der Schlüssel nie wieder zwischen Client und Server übertragen werden.

Das andere häufig verwendete API-Client-Geheimnis ist lediglich ein geheimer Berechtigungsnachweis (wie Sie möglicherweise in einer typischen OAuth2-Zugriffstokenanforderung sehen). Dieser Berechtigungsnachweis wird bei jeder Anforderung übertragen und sollte daher nur über einen verschlüsselten Kanal (z. B. HTTPS) übertragen werden. In diesem Fall muss der Server nur genügend Informationen aufbewahren, um zu überprüfen, ob der vom Client angegebene geheime Wert korrekt ist, sodass das Geheimnis gehasht werden kann und sollte. In diesem Fall fungiert das Geheimnis effektiv als Passwort, und daher sollten die gleichen Vorsichtsmaßnahmen getroffen werden.

Haftungsausschluss: Ich bin kein Sicherheitsforscher, und Sie sollten unbedingt mehr zu diesem und jedem anderen Thema recherchieren, bevor Sie blindlings den Ratschlägen zu diesem StackExchange folgen.

tl; dr Der wichtigste Aspekt ist, dass verschiedene APIs das Geheimnis auf unterschiedliche Weise verwenden können. Es ist wichtig zu verstehen, wie Ihre API das Client-Geheimnis verwendet, um Best Practices für das Speichern zu bewerten.

8
Nick Sloan

Ich habe meine eigenen zwei Cent wegen eines Problems eingezahlt, das noch nicht erwähnt wurde. Insbesondere stimme ich dem zu, was @NickSloan gesagt hat, aber mit einer weiteren Einschränkung.

Es gibt einen weiteren wichtigen Unterschied zwischen einem API-Schlüssel und einem Kennwort. API-Schlüssel sind für Ihre Site eindeutig. Der Teil, der die Kennwortsicherheit so wichtig macht, ist die Kennwortfreigabe. Wenn jemand das Kennwort erhält, das ein Benutzer auf Ihrer Website gespeichert hat, ist nicht nur Ihre Website gefährdet, sondern jede andere Website, für die der Benutzer dieses Kennwort (und die E-Mail-Adresse/den Benutzernamen) verwendet hat. Viele Benutzer verwenden Kennwörter auf kritischen Websites wieder: Banken, soziale Medien, E-Mail usw. Dies bedeutet, dass es bei einer guten Kennwortsicherheit weniger um den Schutz des Zugriffs auf Ihre Website als vielmehr um den Schutz Ihrer Benutzer auf anderen Websites geht. Wir können Benutzer nicht dazu zwingen, die Sicherheit besser zu machen, daher müssen wir das Schlimmste annehmen und zusätzliche Schritte unternehmen, damit sie ihre eigene Privatsphäre schützen können.

Ein API-Schlüssel ist ein völlig anderes Szenario, da er für Ihre Site eindeutig ist. Wenn es gestohlen wird, erhält der Angreifer Zugriff auf Ihre Website, erhält jedoch nichts, was er gegen die Bank/E-Mail/etc. Dieser Person einsetzen kann. Dies bedeutet, dass das Risiko für API-Schlüssel tatsächlich niedriger ist als das für Kennwörter. Sie befinden sich nicht ganz im selben Ball Park: API-Schlüssel ähneln eher Sitzungskennungen als Kennwörtern.

Wenn Sie verstehen, dass diese eher Sitzungskennungen als Kennwörter ähneln, erhalten Sie einige praktische Einblicke in den richtigen Schutz solcher Schlüssel. Beachten Sie, dass die folgende Diskussion auf API-Schlüssel für Dinge wie OAuth Anmeldeinformationen und keine Verschlüsselungsanmeldeinformationen (wie von @NickSloan in seiner Antwort erläutert) anwendbar ist.

Die größte Bedrohung für Passwörter sind Phishing-Angriffe und gehackte Datenbanken. Deshalb speichern wir sie gehasht in unseren Datenbanken. Die größten Bedrohungen für API-Schlüssel sind dieselben wie für Sitzungsschlüssel: Schwachstellen in Front-End-Anwendungen wie XSS-Schwachstellen, MIM und dergleichen. Es ist wichtig zu beachten, dass die Front-End-Anwendung das Kennwort in unverschlüsselter Form benötigt, sodass das Hashing des API-Schlüssels Ihnen nichts bringt, wenn die Person, die es am wahrscheinlichsten gestohlen hat, es im Klartext benötigt.

Stattdessen schützen Sie eine Sitzungskennung (oder OAuth Token oder clientspezifischer API-Schlüssel) hauptsächlich, indem Sie den Client verfolgen. Wenn eine Sitzungskennung über XSS oder andere Mittel vom Client gestohlen wird Ein typisches Ergebnis ist, dass diese Kennung vom Angreifer auf einem neuen Gerät verwendet wird. Das bedeutet, dass plötzlich ein alter Schlüssel mit einem neuen Benutzeragenten angezeigt wird. Eine solche Änderung ist leicht zu erkennen und zu beheben: Alle API-Schlüssel werden sofort ungültig. Insbesondere bei OAuth -Anfragen) ist dies für den Benutzer sehr schmerzlos: Sie melden sich einfach wieder an und erhalten sofort einen neuen, während jemand, der nur den Schlüssel gestohlen hat (und hat nicht das Passwort) ist zurück zum Zeichenbrett.

Dies ist eine häufig genug vorkommende Verteidigungsmaßnahme, bei der ein intelligenterer Hacker auch versucht, den mit dem gestohlenen Schlüssel verknüpften Benutzeragenten aufzuzeichnen und in allen zukünftigen Anforderungen zu verwenden von mehreren IP-Adressen. Wie alles andere auf der Welt kann dies ein Katz-und-Maus-Spiel sein, aber es gibt einige wichtige Take-Aways:

  1. Ein API-Schlüssel/OAuth-Token/eine Sitzungs-ID ist eigentlich nur eine Möglichkeit, sich an einen Benutzer auf einem bestimmten Gerät zu erinnern, sodass er nicht auf jeder Seite sein Kennwort eingeben muss. Im Zweifelsfall können Sie daher einfach alle autorisierten Schlüssel löschen und den Benutzer zwingen, sich erneut anzumelden.
  2. In allen drei Fällen ist es wichtig, eine aktive Sicherheit in Bezug auf diese Dinge zu haben und zu erkennen/zu reagieren, wenn etwas faul passiert, da der Verlust von Schlüssel/Token/ID zu einer Gefährdung eines Kontos führt. Wenn Sie jemals von Facebook/Google/etc Benachrichtigungen über jemanden erhalten haben, der versucht, sich aus Mexiko in Ihr Konto einzuloggen, liegt dies daran, dass ein Sicherheitsbeamter irgendwo seine Arbeit richtig macht.
  3. Die primären Angriffsvektoren für Schlüssel/Tokens/IDs unterscheiden sich von denen von Passwörtern. Möglicherweise möchten Sie sie weiterhin in Ihrer Datenbank hashen (auch hier handelt es sich nicht um Verschlüsselungsdaten, die im Klartext vorliegen müssen), aber Sie können sie nicht einfach in Ihrer Datenbank hashen und sich selbst als sicher bezeichnen. Sie müssen sicherstellen, dass sie gegen eine ganze Reihe neuer Angriffsmethoden geschützt sind. Wenn Sie sie nur als Passwörter betrachten, werden Sie einige wichtige Teile des Gesamtbildes übersehen.
5
Conor Mancone

Einer der Hauptgründe, warum Kennwörter vor dem Speichern gehasht werden, ist der Schutz vor einem Angreifer, der einen schreibgeschützten Zugriff auf die Datenbank erhält . Auf diese Weise kann ein Angreifer, wenn er die Liste der Anmeldeinformationen erhält, diese immer noch nicht direkt verwenden, da die Kennwörter gehasht/gesalzen sind.

Und dies ist nicht nur ein theoretisches Problem, das wir hier zu lösen versuchen, diese Art von Angriffen passieren wirklich ( auch für Hauptakteure in) die Industrie ), und richtiges Hashing hilft, die Auswirkungen eines Angriffs zu mildern.

Wenn Sie Benutzern die Authentifizierung mithilfe eines API-Geheimnisses ermöglichen, wurde das API-Geheimnis effektiv zu einem Kennwort . Aus Sicherheitsgründen sollten sie dasselbe haben Schutzmechanismen wie normale Passwörter haben.

Amazon selbst jetzt erlaubt nicht das Abrufen des API-Geheimnisses . Wenn Sie es vergessen, müssen Sie nach einem neuen fragen.

2
Pedro Rodrigues

Nein, es ist nicht in Ordnung für irgendeine Art von Dienstleistungen.

Implementierung

1. Generieren Sie bei einer Benutzerverbindung mit dem Anmeldekennwort einen aus seinem Kennwort abgeleiteten Schlüssel, um die Daten für diesen Benutzer zu verschlüsseln und in einer Sitzung auf dem Server zu speichern.

Auf diese Weise hat jeder Benutzer einen eindeutigen Schlüssel. Dieser abgeleitete Schlüssel darf nicht umkehrbar sein, dies ist der Hauptpunkt. Die Verwendung von hash_mac oder einer anderen Hashing-Methode mit Salt und/oder Hauptschlüssel ermöglicht dies.

2. Verwenden Sie diesen Schlüssel, um das generierte API-Geheimnis mit AES 256 mit einem zufälligen iv für jeden Benutzer zu verschlüsseln.

Oder

2.bis Verwenden Sie diesen Schlüssel, um im letzten Moment den echten Verschlüsselungsschlüssel zu generieren und die API-Methode auf die gleiche Weise wie in 2. zu verschlüsseln, um schwebende Kennwörter im Speicher zu vermeiden.

. Speichern Sie das iv in der Datenbank zusammen mit der Benutzer-ID und der App-ID in einer dedizierten Tabelle

4. Speichern Sie das verschlüsselte API-Geheimnis in der Datenbank in der entsprechenden Tabelle.

Verwendung

Wenn der Benutzer eine Verbindung zu seinem Control Panel herstellt, können Sie den Schlüssel neu erstellen, die iv abrufen, das API-Geheimnis für diesen Benutzer entschlüsseln und im Klartext anzeigen. Sie zeigen auch den Schlüssel an und fragen beim API-Aufruf nach beiden, damit Sie das App-Geheimnis überprüfen können.

Wenn Sie vermeiden möchten, dass der Schlüssel angezeigt wird, und ihn nicht beim API-Aufruf anfordern müssen, können Sie zur Authentifizierung dieselbe Methode wie für die Anmeldung verwenden. Das heißt, Sie können eine weitere Tabelle erstellen, um einen zufälligen Schlüssel/Salt für jede Client-App zu speichern und eine hash_mac-Version des API-Geheimnisses zu speichern. Daher sind nur die API-ID und das API-Geheimnis erforderlich, um die API-Anforderung zu authentifizieren. aber es ist mehr Arbeit.

Anmerkung

Dies entspricht praktisch der Antwort von @Polynomial.

Auf diese Weise ist es für jemanden, der Ihren Server und Ihre Datenbank hackt, sehr, sehr schwierig, die Anmeldeinformationen Ihrer Benutzer zu stehlen und in ihrem Namen einen API-Anruf zu tätigen. Sie können jetzt beurteilen, ob eine Anforderung, die von einem API-Client angenommen wurde, der richtige Client ist oder deren Leckage.

Wenn der Benutzer sein Passwort verliert, generieren Sie ein neues API-Geheimnis und einen neuen Schlüssel aus seinem neuen Passwort neu.

0
Nicolas Manzini