iToverDose/Software· 10 MAI 2026 · 12:07

Schnelle API-Authentifizierung: Warum HMAC-SHA256 Bcrypt übertrifft

Eine API mit Bcrypt-Authentifizierung verbrauchte pro Anfrage fast eine Sekunde Rechenzeit – ein unnötiger Flaschenhals. Wie ein Wechsel zu HMAC-SHA256 und Client-seitigem Caching die Latenz um 99 % reduzierte und die Skalierbarkeit revolutionierte.

DEV Community3 min0 Kommentare

Es begann mit einer simplen Zeitmessung. Was als Routine-Check gedacht war, entpuppte sich als Albtraum: Jede authentifizierte API-Anfrage dauerte im Schnitt 946 Millisekunden – fast eine ganze Sekunde – bevor überhaupt eine Antwort versendet wurde. Der Grund? Eine vermeintlich sichere Wahl: Bcrypt zur Validierung von API-Schlüsseln.

Warum Bcrypt für API-Schlüssel die falsche Wahl ist

Bei der Implementierung der Authentifizierung bei VesselAPI wurde Bcrypt eingesetzt, weil es als Standard für Passwort-Hashes galt. Jeder API-Schlüssel wurde mit einem Kostenfaktor von 10 gehasht und in der PostgreSQL-Datenbank gespeichert. Pro Anfrage musste das System dann bis zu elf gespeicherte Hashes mit dem eingehenden Schlüssel vergleichen – ein linearer Scan mit einer Latenz von 65 bis 100 Millisekunden pro Vergleich.

Doch API-Schlüssel unterscheiden sich fundamental von Passwörtern: Sie sind 256-Bit-kryptografisch zufällige Zeichenfolgen, die praktisch nicht brute-force-angreifbar sind. Selbst bei einer Billion Versuchen pro Sekunde würde eine Entschlüsselung länger dauern als die voraussichtliche Lebensdauer der Sonne. Die Absicht hinter Bcrypts Trägheit – Schutz vor Offline-Angriffen – war hier schlicht irrelevant.

Stattdessen lag das Hauptrisiko in der möglichen Kompromittierung der Schlüssel: durch versehentliche Veröffentlichung in öffentlichen Repos, Protokollierung in Logs oder Diebstahl von Clients. Bcrypt bot dafür keinen Schutz. Eine bessere Lösung erforderte eine deterministische, indizierbare Hash-Funktion – kombiniert mit einem serverseitigen Geheimnis, das den Zugriff auf die Hashes zusätzlich absichert.

Der Wechsel zu HMAC-SHA256 und die Macht der deterministischen Hashes

Die Lösung bestand aus zwei Komponenten: HMAC-SHA256 zur schnellen Validierung der API-Schlüssel und einem serverseitigen "Pepper" – einem 64-stelligen Zufallsgeheimnis, das aus AWS Secrets Manager geladen wird. Der Ablauf ist denkbar einfach: Der eingehende API-Schlüssel wird mit HMAC-SHA256 unter Verwendung des Peppers gehasht. Der resultierende Hash wird in der Datenbank gespeichert und kann bei Anfragen direkt indiziert abgefragt werden.

// Vorher: Bcrypt-Vergleich aller gespeicherten Hashes
for _, stored := range allKeyHashes {
    if err := bcrypt.CompareHashAndPassword([]byte(stored), []byte(apiKey)); err == nil {
        return stored, nil
    }
}

// Nachher: HMAC + indizierte Abfrage
mac := hmac.New(sha256.New, []byte(pepper))
mac.Write([]byte(apiKey))
keyHMAC := hex.EncodeToString(mac.Sum(nil))
return db.VerifyApiKeyHMAC(keyHMAC) // indizierte Abfrage, <1ms

Der Unterschied ist dramatisch. Während Bcrypt pro Vergleich etwa 100 Millisekunden benötigte, dauert die Berechnung des HMAC-SHA256-Hashes nur etwa eine Mikrosekunde. Selbst mit Netzwerk-Overhead reduzierte sich die Authentifizierungszeit von 946 Millisekunden auf etwa 811 Millisekunden – eine deutliche Verbesserung, aber noch nicht optimal.

Null Datenbank-Abfragen: Wie Client-seitiges Caching die Latenz eliminiert

Der nächste logische Schritt bestand darin, die Anzahl der Datenbankabfragen zu minimieren. Anstatt bei jeder Anfrage die Datenbank zu belasten, wurden zwei sync.Map-Instanzen im Authentifizierungsdienst implementiert:

  • keyCache: Mappt HMAC-Hashes auf Metadaten der API-Schlüssel.
  • userCache: Mappt Benutzer-IDs auf Abonnement- und Kontingentinformationen.

In einem stabilen Zustand – bei einem erwärmten Cache – laufen authentifizierte Anfragen komplett ohne Datenbankzugriff ab. Der Prozess sieht dann wie folgt aus:

  • Extrahieren des Bearer-Tokens aus der Anfrage.
  • Berechnung des HMAC-SHA256-Hashes mit dem Pepper (~1 Mikrosekunde).
  • Abfrage des keyCache (einige Dutzend bis Hundert Nanosekunden).
  • Atomare Inkrementierung eines lokalen Zählers für die Nutzung (~25 Nanosekunden).
  • Überprüfung der Kontingentgrenzen im Speicher (einige Nanosekunden).

Vergleich: Vor und nach der Optimierung

Vorher (pro Anfrage):

  • Extrahieren des Bearer-Tokens.
  • Laden aller Schlüssel-Hashes aus der Datenbank.
  • Bcrypt-Vergleich aller Hashes (bis zu 11 × ~100ms CPU-Zeit).
  • Datenbankabfrage zur Überprüfung des Kontingents.
  • Datenbankabfrage zum Hochzählen der Nutzung.
  • 3 bis 4 Roundtrips, bis zu 1,1 Sekunden CPU-Zeit.

Nachher (Cache erwärmt):

  • Extrahieren des Bearer-Tokens.
  • HMAC-SHA256-Berechnung mit Pepper (~1µs).
  • sync.Map-Lookup im keyCache (einige ns bis µs).
  • Atomare Nutzungserhöhung (einige ns).
  • Speicherbasierte Kontingentprüfung (einige ns).
  • Null Datenbankabfragen.

Fazit: Optimierung als strategische Investition

Die Migration von Bcrypt zu HMAC-SHA256 war nicht nur eine technische Verbesserung, sondern eine grundlegende Änderung der Architektur. Durch die Kombination von deterministischen Hashes, serverseitigen Geheimnissen und intelligentem Caching wurde die Authentifizierung von einem Flaschenhals zu einem reibungslosen Prozess. Die Latenz sank um über 90 %, und die Skalierbarkeit stieg proportional zur eingesparten CPU-Zeit.

Diese Optimierung zeigt, dass nicht jede Sicherheitsmaßnahme universell einsetzbar ist. Was für Passwörter funktioniert, kann für API-Schlüssel kontraproduktiv sein. Der Schlüssel liegt darin, die spezifischen Anforderungen und Bedrohungsmodelle zu verstehen – und dann die passende Technologie auszuwählen.

Für Teams, die ähnliche Herausforderungen bewältigen müssen, lautet die Empfehlung: Messen Sie die tatsächliche Performance, hinterfragen Sie etablierte Praktiken und optimieren Sie gezielt dort, wo der größte Nutzen entsteht. Die Ergebnisse sprechen für sich.

KI-Zusammenfassung

API anahtarlarını doğrulamak için bcrypt kullanmanın performans kaybını öğrenin. HMAC-SHA256 ve cache kullanımıyla 1 saniyelik doğrulama süresini nasıl milisaniyelere indirebilirsiniz?

Kommentare

00
KOMMENTAR SCHREIBEN
ID #ZPS73L

0 / 1200 ZEICHEN

Menschen-Check

8 + 6 = ?

Erscheint nach redaktioneller Prüfung

Moderation · Spam-Schutz aktiv

Noch keine Kommentare. Sei der erste.