it-swarm.com.de

Wie ist das Speichern eines geheimen API-Schlüssels im Klartext (in einer Datenbank) sicher?

Die Antworten auf diese Frage Ist es in Ordnung, wenn API-Geheimnisse im Klartext gespeichert oder entschlüsselt werden können? sind für mich etwas beunruhigend. Ich versuche zu überlegen, wie sicher das Speichern eines geheimen Schlüssels im Klartext in irgendeiner Weise ist.

So stelle ich mir ein API-Zugriffsschlüssel-/Geheimschlüssel-basiertes System vor:

  1. Der Client nimmt den Anforderungstext entgegen und wendet die HMAC-Funktion mit secretKey an, was zu signature führt
  2. Der Client fügt signature und accessKey zur Anforderung hinzu (effektiv als Authentifizierungsheader) und sendet sie an den Server
  3. Der Server extrahiert accessKey aus der Anfrage und sucht nach dem entsprechenden serverSecretKey
  4. Der Server nimmt den Anforderungstext entgegen und wendet die HMAC-Funktion mit der Serverversion von serverSecretKey an, was zu serverSignature führt
  5. Server vergleicht signature mit serverSignature; Wenn sie übereinstimmen, sind wir gut - wir wissen, dass der Client sowohl einen gültigen Zugriffsschlüssel als auch einen gültigen geheimen Schlüssel hat

Bevor ich fortfahre, macht der Rest dieser Frage mehr oder weniger keinen Sinn - lassen Sie mich bitte wissen, ob das obige Verständnis von API-Zugriff/geheimen Schlüsseln gültig ist oder nicht :-)

Vorausgesetzt, mein Verständnis ist gültig - meine Frage geht zurück auf die Speicherung des geheimen Schlüssels - er muss im Klartext gespeichert werden, damit das obige System funktioniert.

Was passiert also, wenn ein Angreifer Zugriff auf meine Datenbank erhält, die alle API-Zugriffsschlüssel und geheimen Schlüssel meiner Clients enthält? Wären sie nicht in der Lage, eine beliebige Kombination aus Zugriff und geheimem Schlüssel zu verwenden und sich gerne als Client auszugeben?

Ich betrachte dies aus der Perspektive von bcrypt - ed Passwörtern. Wenn ein Angreifer Zugriff auf eine Datenbank mit einer ganzen Reihe von bcrypt - Passwörtern erhält, hat er eine Menge Arbeit vor sich sie, um diese Datenbank für sie lohnenswert zu machen, da das brutale Erzwingen einer Reihe von bcrypt - ed-Passwörtern rechenintensiv ist. Das fühlt sich viel sicherer an, als irgendwo geheime API-Schlüssel im Klartext in einer Datenbank zu speichern.

Es scheint, als ob eine Kombination aus API-Zugriffsschlüssel und geheimem Schlüssel wirklich nur Schutz vor Manipulationen an einer Nachricht bietet (da die in den obigen Schritten 1 und 2 berechnete digitale Signatur an den geheimen Schlüssel gebunden ist) und nicht wirklich geben Sie die Gewissheit, dass der Kunde der ist, von dem er sagt, dass er er ist. Ich sehe nicht, wie es eine Sicherheitsstufe bietet, die mit bcrypt - ed Passwörtern vergleichbar ist.

Was fehlt mir hier?

16
Rob

Ihre Überlegungen dazu sind zu schwarz und weiß: sicher oder unsicher. Hier gibt es keinen Safe, nur ein Spektrum von Risiken.

Unternehmen, die diese APIs bereitstellen, treffen ein Urteil und versuchen, das Risiko mit der Leistung in Einklang zu bringen. Nicht alle dieser API-Aufrufe müssen über SSL erfolgen. Denken Sie darüber nach, ein Bild in S3 hochzuladen. Muss es verschlüsselt werden? Wahrscheinlich nicht. Die Hauptanforderung ist, dass die Anrufe authentifiziert und autorisiert sind. Denken Sie an eine Million verschiedene Aufrufe von SDB oder SQS. Wie viel Overhead auf Client- und Serverseite wird SSL verursachen? Grundsätzlich ist SHA2 schnell und SSL teuer und wird jetzt mit 1.000.000 multipliziert.

Besteht das Risiko, die API-Schlüssel auf der Serverseite im Klartext zu halten? Sicher, aber diese Unternehmen setzen darauf, dass sie andere Abschwächungen in Bezug auf die wichtigsten Geschäfte vornehmen können, die das Risiko auf ein akzeptables Maß senken. (Wenn ich letztendlich Zugriff auf Ihren Schlüsselspeicher, Hash oder Klartext bekomme, gibt es mehrere böswillige Dinge, die ich tun kann, indem ich meinen geheimen Schlüssel gegen Ihren eintausche.)

Zu Ihrer Aussage: "Gibt nicht wirklich die Gewissheit, dass der Kunde der ist, von dem er sagt, dass er er ist."

Dies gilt für fast alle Authentifizierungsschemata. Wenn sich jemand mit meinem Benutzernamen und Passwort auf dieser Site anmeldet, beweist dies nicht, dass er ich bin, sondern nur, dass er meine Anmeldeinformationen besitzt. Wenn jemand meinen Fingerabdruck verwendet, um ein biometrisches Schloss zu entsperren, bedeutet dies, dass er meinen Daumenabdruck auf eine Weise bereitstellen kann, die das Schloss akzeptiert. Was sich hier ändert, ist, wie schwierig das ist. Das Stehlen von Anmeldeinformationen ist möglicherweise nicht so schwierig. Es ist wahrscheinlich schwieriger, sich als Fingerabdrücke auszugeben, aber nicht unmöglich.

7
u2702

Kurz gesagt, es ist nicht so, aber der geheime Schlüssel muss nicht unbedingt im Klartext auf dem Server gespeichert werden. Es könnte selbst mit Informationen verschlüsselt (aber nicht gehasht werden, wie andere erklärt haben), die Teil einer Client-Anfrage sind.

Wenn Sie sich bei einem Dienst anmelden, der Ihre geheimen Schlüssel anzeigt, müssen die Schlüssel nicht im Klartext gespeichert worden sein, da sie mit einer Einwegableitung des Kennworts verschlüsselt werden könnten, das für die Anmeldung verwendet wurde und das der Sitzung zugeordnet bleibt . Während der geheime Schlüssel beim Zugriff auf die Sitzungsdaten entdeckt werden konnte, war jeweils nur eine Teilmenge der geheimen Clientschlüssel gefährdet.

4
Nick

Ich habe kürzlich eine Antwort auf die andere Frage hinzugefügt, die meiner Meinung nach auch hier relevant ist. Ich habe meine Antwort leicht bearbeitet, um Ihre Frage direkter zu beantworten:

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.

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 API-Schlüssel eher Sitzungskennungen als Kennwörtern ähneln.

Unter Sicherheitsgesichtspunkten werden Sie das Problem klarer betrachten, wenn Sie API-Schlüssel nicht als Kennwörter, sondern als Sitzungs-IDs betrachten, insbesondere in Fällen, in denen API-Schlüssel automatisch zugewiesen werden können (OAuth und dergleichen). Ja, API-Schlüssel können gestohlen werden, was dazu führt, dass Ihr Konto kompromittiert wird. Die Art und Weise, wie Schlüssel gestohlen werden können, unterscheidet sich jedoch erheblich von der Art und Weise, wie ein Kennwort gestohlen werden kann. Insbesondere wird ein Passwort (theoretisch) nur an zwei Stellen gespeichert: im Kopf des Benutzers und in Ihrer Datenbank. Infolgedessen stellt Ihre Datenbank die größte Bedrohung für die Kennwortsicherheit dar (wenn wir Phishing-Angriffe ignorieren), und die Wiederverwendung von Kennwörtern erhöht die tatsächliche Gefahr für Endbenutzer, falls Ihre Datenbank mit Klartextkennwörtern gestohlen wird.

Im Fall einer Sitzungskennung oder eines API-Schlüssels ist jedoch keine dieser Analysen wahr. API-Schlüssel werden in Ihrer Datenbank gespeichert, sie werden jedoch auch in jedem Client gespeichert, der das Kennwort verwendet. Dies kann sich im Speicher einer Front-End-Javascript-Anwendung (die für XSS-Angriffe anfällig ist) befinden, einer Konfigurationsdatei auf einem Server, der in die API integriert ist (die für eine völlig andere Gruppe von Angriffen anfällig ist), oder wer weiß wo sonst. Infolgedessen ist die Datenbank nicht mehr der primäre Angriffsvektor, von dem aus auf API-Schlüssel zugegriffen werden kann. Dies ändert definitiv die Sicherheitsprioritäten.

Um noch einen Punkt hervorzuheben, sind Sitzungskennungen die richtige Perspektive, um API-Schlüssel anzuzeigen. Jede Website, die zum Speichern von Benutzerdaten auf Sitzungen angewiesen ist, verfügt normalerweise über eine Sitzungs-ID, die ebenfalls in der Datenbank gespeichert und mit dem Browser des Benutzers in einem Cookie gespeichert wird. Wenn Ihre Datenbank gehackt und heruntergeladen wird, sind die Sitzungen Ihrer Benutzer daher vollständig gefährdet. Ein böswilliger Benutzer kann eine Sitzungs-ID abrufen, sein Cookie für Ihre Website bearbeiten und sich ohne großen Aufwand als jeder Benutzer anmelden. Das Hashing von Sitzungs-IDs vor dem Speichern in der Datenbank würde diesen bestimmten Angriff stoppen, aber nichts würde die XSS-Angriffe stoppen, die häufiger zum Stehlen von Sitzungen verwendet werden.

2
Conor Mancone