API-Schlüssel erklärt: Länge, Format, Speicherung und Rotation

Aktualisiert:

Ein API-Schlüssel ist eine lange Zufallszeichenkette, die ein Programm bei jeder Anfrage mitschickt, um zu zeigen, welche Anwendung anfragt. Anders als ein Passwort muss ihn sich niemand merken, deshalb kann er so lang und zufällig sein wie nötig. Anders als ein Anmelde-Token gilt er meist, bis ihn jemand widerruft. Die Dokumentation von Google fasst das Risiko zusammen: API-Schlüssel sind Inhaber-Anmeldedaten – wer einen besitzt, kann ihn verwenden.

Dieser vierte Teil der Reihe über Sicherheit behandelt das ganze Leben eines Schlüssels: wie viele Zufallsbits er braucht, in welchem Format man ihn schreibt, warum es Präfixe wie sk_live_ gibt, wie man ihn sendet, was der Server speichern sollte und wie man ihn rotiert und widerruft.

API-Schlüssel, Passwort oder Zugriffstoken?

Alle drei beweisen einem Server etwas, deshalb werden sie oft verwechselt. Der Unterschied liegt darin, wer sie erzeugt, wie lange sie gelten und was der Server aufbewahrt:

ZugangsdatenErzeugt vonGültigDer Server speichert
Passworteinem Menschenbis der Mensch es änderteinen langsamen Hash (Argon2id, scrypt, bcrypt)
API-Schlüsseleinem Zufallsgeneratorbis er rotiert oder widerrufen wirdeinen schnellen Hash wie SHA-256
Zugriffstoken (OAuth, JWT)dem Anmeldeserver, nach einer AnmeldungMinuten bis Stundeneine zu prüfende Signatur oder einen Eintrag des Tokens

Ein API-Schlüssel kennzeichnet normalerweise eine Anwendung oder eine Integration, keinen Menschen. Wo ein Schlüssel an die Stelle einer Anmeldung durch einen Menschen treten würde, ist ein Zugriffstoken aus einem richtigen Anmeldeablauf meist das bessere Werkzeug, wie der vorige Teil über JSON Web Tokens erklärt.

Wie lang ein Schlüssel sein sollte

Was einen Schlüssel schützt, ist die Zahl der Zufallsbits darin, nicht seine Länge in Zeichen. Jedes Bit verdoppelt die Zahl möglicher Schlüssel: 128 Zufallsbits ergeben etwa 3,4 × 10³⁸ Schlüssel. Selbst ein Millionstel davon bei einer Milliarde Versuchen pro Sekunde durchzuprobieren, dauerte etwa 10¹⁶ Jahre, fast eine Million Mal das Alter des Universums. 128 Bit sind deshalb ein solides Minimum, und 256 Bit kosten nur ein paar Zeichen mehr.

Die Bits müssen aus einem kryptografischen Zufallsgenerator stammen. Im Browser ist das crypto.getRandomValues(); MDN warnt, dass Math.random() keine kryptografisch sicheren Zahlen liefert und für nichts verwendet werden darf, was mit Sicherheit zu tun hat. Serversprachen haben eigene Entsprechungen, etwa das Modul secrets in Python oder crypto.randomBytes() in Node.js.

GitHub hat seine OAuth-Tokens bei der Umstellung des Formats 2021 von 160 auf 178 Bit Entropie angehoben. Ein Fall braucht noch mehr: ein Geheimnis, das JSON Web Tokens mit HMAC signiert. RFC 7518 verlangt einen Schlüssel, der mindestens so lang ist wie die Hash-Ausgabe: 256 Bit für HS256, 384 für HS384 und 512 für HS512.

Formate: base62, hexadezimal oder base64url

Die Zufallsbits müssen als Text geschrieben werden. Das Alphabet bestimmt, wie viele Zeichen nötig sind und wo man den Schlüssel problemlos einfügen kann:

FormatZeichenBit pro ZeichenLänge für 256 Bit
base62a–z, A–Z, 0–95,9543
hex0–9, a–f464
base64urla–z, A–Z, 0–9, - und _643

base62 hat sich für Schlüssel durchgesetzt, weil es nur aus Buchstaben und Ziffern besteht: nichts, was eine URL, eine Shell oder eine Konfigurationsdatei besonders behandelt, und ein Doppelklick markiert den ganzen Schlüssel. Hexadezimal ist länger, funktioniert aber dort, wo nur 0–9 und a–f erlaubt sind. base64url aus RFC 4648 ist am kürzesten, aber sein - kann die Doppelklick-Markierung unterbrechen. Standard-Base64 ist eine schlechte Wahl, weil + und / in URLs maskiert werden müssen.

base62 richtig zu erzeugen, verlangt Sorgfalt: Ein Zufallsbyte hat 256 Werte, und 256 ist kein Vielfaches von 62, deshalb macht ein einfaches Byte % 62 die ersten acht Zeichen etwas wahrscheinlicher. Ein guter Generator verwirft Bytes ab 248, wie es der Generator von nTools tut.

Präfixe und Secret Scanning

Viele Anbieter beginnen ihre Schlüssel mit einem festen, lesbaren Präfix. Die geheimen Schlüssel von Stripe beginnen mit sk_live_ oder sk_test_, die veröffentlichbaren mit pk_ und die eingeschränkten mit rk_. Seit 2021 beginnen die Tokens von GitHub mit ghp_ für persönliche Zugriffstokens, gho_ für OAuth-Tokens und ghs_ für Server-zu-Server-Tokens.

Ein Präfix ist nicht geheim und macht den Schlüssel nicht stärker, erfüllt aber drei nützliche Aufgaben. Man sieht auf einen Blick, wofür ein Schlüssel ist und ob es ein Testschlüssel ist. GitHub hat den Unterstrich gewählt, weil er kein Base64-Zeichen ist – zufällige Zeichenketten wie Hashes können also nicht zufällig wie ein Token aussehen – und weil ein Doppelklick das ganze Token markiert. Vor allem lässt ein Präfix Scanner geleakte Schlüssel finden: Das Secret Scanning von GitHub durchsucht die gesamte Git-Historie aller Branches und benachrichtigt, wenn es das Geheimnis eines Partneranbieters findet, diesen Anbieter, der den Schlüssel widerrufen kann.

GitHub beendet seine Tokens außerdem mit einer 32-Bit-CRC32-Prüfsumme in sechs base62-Zeichen. Sie bringt keine Sicherheit, erlaubt einem Scanner aber, zufällige Zeichenketten offline auszusortieren, ohne den Server zu fragen, ob das Token existiert.

Im Header senden, nie in der URL

RFC 6750, das Inhaber-Tokens für OAuth 2.0 definiert, sagt, dass Clients sie im Header Authorization senden und nicht in Seiten-URLs übergeben sollen, weil Adressen im Browserverlauf und in Serverprotokollen landen. Google gibt denselben Rat für seine eigenen API-Schlüssel und bietet dafür einen Header an. Dasselbe RFC verlangt TLS: Einen über einfaches http gesendeten Schlüssel kann jeder auf dem Weg mitlesen.

Was der Server speichern sollte

Der Server muss den Schlüssel selbst nicht aufbewahren, nur eine Möglichkeit, ihn wiederzuerkennen. Speichern Sie einen Hash des Schlüssels, etwa seinen SHA-256; kommt eine Anfrage, hashen Sie den mitgeschickten Schlüssel und suchen diesen Hash. Gelangt die Datenbank nach außen, lässt sich mit den Hashes die API nicht aufrufen, und die Schlüssel lassen sich daraus nicht zurückgewinnen.

Passwörter brauchen einen langsamen Hash, weil, wie das Password Storage Cheat Sheet der OWASP erklärt, ein schneller Hash wie SHA-256 Angreifern erlaubt, sehr viele Versuche in kurzer Zeit zu machen. Diese Überlegung setzt voraus, dass Passwörter erraten werden können. Ein Schlüssel mit 256 Zufallsbits kann das nicht, also genügt ein einzelner schneller Hash, und jede Anfrage bleibt schnell.

Weil nur der Hash aufbewahrt wird, kann der vollständige Schlüssel nur einmal angezeigt werden, bei seiner Erstellung. Stripe macht es so bei den geheimen Live-Schlüsseln, die Sie selbst anlegen: Das Dashboard zeigt den Schlüssel ein einziges Mal und kann ihn nicht erneut anzeigen. Bewahren Sie das Präfix und die letzten Zeichen im Klartext auf, wenn Menschen ihre Schlüssel unterscheiden müssen.

Schlüssel aus dem Code heraushalten

Geleakte Schlüssel findet man meist dort, wo Entwickler sie aus Bequemlichkeit hingelegt haben. Stripe warnt, dass Angreifer öffentliche Repositorys ständig nach API-Schlüsseln durchsuchen und dass selbst private Repositorys offengelegt werden können. Seine Ratschläge, die Google und die OWASP teilen:

Rotation und Widerruf

Jeder Schlüssel sollte sich kurzfristig ersetzen lassen. Rotieren heißt: einen neuen Schlüssel anlegen, alle Anwendungen darauf umstellen und dann den alten löschen. Regelmäßig gemacht, begrenzt das, wie lange ein gestohlener Schlüssel funktioniert, und beweist, wie Stripe betont, dass Sie wissen, wo jeder Schlüssel verwendet wird. Das Stripe-Dashboard lässt alten und neuen Schlüssel bis zu sieben Tage gemeinsam gelten, damit der Wechsel reibungslos klappt.

Wird ein Schlüssel offengelegt – in ein Repository übertragen, in einen Chat kopiert, in ein Protokoll geschrieben –, widerrufen Sie ihn sofort, auch wenn Sie nicht sicher sind, ob ihn jemand gesehen hat. Den Commit zu löschen, reicht nicht: Der Schlüssel kann schon kopiert worden sein und bleibt in der Git-Historie und in jedem Klon. Wo das System es erlaubt, geben Sie Schlüsseln zusätzlich ein Ablaufdatum, damit ein vergessener Schlüssel von selbst ungültig wird.

Einen Schlüssel erzeugen

Der API-Schlüssel-Generator von nTools erzeugt Schlüssel in base62, hexadezimal oder base64url, mit 128 bis 512 Bit, einem optionalen Präfix und auf Wunsch dem SHA-256-Hash für den Server. Er verwendet crypto.getRandomValues() und läuft vollständig in Ihrem Browser: Die Schlüssel werden nirgendwohin gesendet.

API-Schlüssel-Generator

Häufige Fragen

Kann ich eine UUID als API-Schlüssel verwenden?

Eine UUID der Version 4 hat nur 122 Zufallsbits und eine feste, erkennbare Form, und sie wurde als Kennung entworfen, nicht als Geheimnis. Besser ist ein eigener Schlüssel mit 128 Bit oder mehr.

Ist ein im Browser erzeugter Schlüssel sicher?

Ja, wenn er aus crypto.getRandomValues() stammt, dem kryptografischen Generator, den der Browser für seine eigene Sicherheit nutzt, und die Seite ihn nirgendwohin sendet. Der Generator von nTools arbeitet so: Beim Klick auf „Erzeugen“ verlässt keine Anfrage die Seite.

Sollten API-Schlüssel ablaufen?

Wo das System es unterstützt, ja: Ein Ablaufdatum begrenzt den Schaden durch einen vergessenen oder unbemerkt geleakten Schlüssel. Langlebige Schlüssel sind verbreitet, umso wichtiger sind Rotation und schneller Widerruf.

Ich habe einen Schlüssel in Git übertragen. Was nun?

Zuerst widerrufen oder rotieren, dann das Repository bereinigen. Die Historie nachträglich umzuschreiben, macht den Schlüssel nicht wieder sicher, weil er schon kopiert worden sein kann.

Sollte man den Schlüssel verschlüsseln statt hashen?

Nur wenn der Server den Schlüssel später selbst verwenden muss, etwa um damit einen anderen Dienst aufzurufen. Ein Schlüssel, der nur geprüft werden muss, sollte gehasht werden: Dann gibt es nichts zu entschlüsseln, wenn die Datenbank nach außen gelangt.

Zurück in der Reihe ← JSON Web Tokens erklärt: Claims, Signaturen und sichere Prüfung

Quellen

  1. GitHub — Behind GitHub’s new authentication token formats (April 2021)
  2. GitHub Docs — About secret scanning
  3. GitHub Docs — About secret scanning for partners
  4. Stripe — API keys
  5. Stripe — Best practices for managing secret API keys
  6. Google Cloud — Best practices for managing API keys
  7. RFC 6750 — The OAuth 2.0 Authorization Framework: Bearer Token Usage (October 2012)
  8. RFC 7518 — JSON Web Algorithms (JWA) (May 2015)
  9. RFC 4648 — The Base16, Base32, and Base64 Data Encodings (October 2006)
  10. OWASP — Secrets Management Cheat Sheet
  11. OWASP — Password Storage Cheat Sheet
  12. MDN — Crypto: getRandomValues()
  13. MDN — Math.random()

Weitere Ratgeber