Start · Sprachen · JavaScript · Referenz · HmacImportParams

HmacImportParams

Schnittstelle

Wörterbuch-Objekt, das als <code>algorithm</code>-Argument an <code>importKey()</code>, <code>unwrapKey()</code> oder <code>deriveKey()</code> übergeben wird, um einen HMAC-Schlüssel zu erzeugen.

seit JavaScript Baseline: alle modernen Browser (Web Crypto API), Kategorie: webapi

Signatur

interface HmacImportParams extends Algorithm { name: "HMAC"; hash: HashAlgorithmIdentifier; length?: number }

Beschreibung

HmacImportParams ist keine Klasse, die man mit new erzeugt. Es ist ein Wörterbuch (Dictionary), also ein ganz normales JavaScript-Objekt. Es beschreibt, wie die Web Crypto API rohes Schlüsselmaterial als HMAC-Schlüssel behandeln soll. Du übergibst es als algorithm-Parameter an SubtleCrypto.importKey(), SubtleCrypto.unwrapKey() (als unwrappedKeyAlgorithm) oder SubtleCrypto.deriveKey() (als derivedKeyAlgorithm).

Das Wichtigste daran ist die Eigenschaft hash. Sie legt die Hash-Funktion fest, die HMAC intern nutzt, also zum Beispiel SHA-256. Die Hash-Funktion gehört fest zum Schlüssel: Ein mit SHA-256 importierter Schlüssel lässt sich später nicht mit SHA-512 verwenden. Mit dem optionalen length gibst du die Schlüssellänge in Bit an. Fehlt der Wert, gilt beim Import die Länge des übergebenen Schlüsselmaterials.

Typische Einsatzfälle sind das Prüfen von Webhook-Signaturen (z. B. von GitHub oder Stripe), das Signieren von API-Anfragen, JWTs mit HS256 und das Ableiten eines HMAC-Schlüssels aus einem Passwort mit PBKDF2 oder HKDF. Zum Neuerzeugen eines Schlüssels nimmst du dagegen das verwandte Wörterbuch HmacKeyGenParams mit generateKey().

Parameter

Name Typ Default Beschreibung
$name Pflicht string Muss "HMAC" sein.
$hash Pflicht string | Algorithm Die zu verwendende Hash-Funktion: "SHA-1", "SHA-256", "SHA-384" oder "SHA-512", entweder als Zeichenkette oder als Objekt { name: "SHA-256" }.
$length number Länge des Schlüsselmaterials in Bit Optionale Schlüssellänge in Bit. Das ist nur selten nötig. Bei deriveKey() gilt ohne Angabe die Blockgröße der Hash-Funktion (z. B. 512 Bit bei SHA-256).

Rückgabewert

Typ
object
Beschreibung
Das Wörterbuch selbst gibt nichts zurück. importKey(), unwrapKey() und deriveKey() liefern mit diesen Parametern ein Promise<CryptoKey>. Dessen algorithm ist ein HmacKeyAlgorithm mit name, hash und length.

Beispiele

Geheimnis als HMAC-SHA-256-Schlüssel importieren und signieren

const encoder = new TextEncoder();

const key = await crypto.subtle.importKey(
  'raw',
  encoder.encode('mein-geheimer-schluessel'),
  { name: 'HMAC', hash: 'SHA-256' }, // HmacImportParams
  false,                              // nicht exportierbar
  ['sign', 'verify']
);

const signatur = await crypto.subtle.sign('HMAC', key, encoder.encode('Hallo Welt'));
const hex = [...new Uint8Array(signatur)]
  .map((b) => b.toString(16).padStart(2, '0'))
  .join('');

console.log(key.algorithm);
console.log(hex.length);
{ name: 'HMAC', hash: { name: 'SHA-256' }, length: 192 } 64

Webhook-Signatur prüfen (z. B. GitHub, X-Hub-Signature-256)

const hexToBytes = (hex) =>
  new Uint8Array(hex.match(/.{2}/g).map((b) => parseInt(b, 16)));

const verifyWebhook = async (secret, body, signatureHeader) => {
  const enc = new TextEncoder();
  const key = await crypto.subtle.importKey(
    'raw',
    enc.encode(secret),
    { name: 'HMAC', hash: { name: 'SHA-256' } },
    false,
    ['verify']
  );
  const sigHex = signatureHeader.replace(/^sha256=/, '');
  // verify() vergleicht in konstanter Zeit
  return crypto.subtle.verify('HMAC', key, hexToBytes(sigHex), enc.encode(body));
};

const ok = await verifyWebhook('geheim', '{"event":"push"}', 'sha256=00ff');
console.log(ok);
false

HMAC-Schlüssel aus Passwort per PBKDF2 ableiten

const enc = new TextEncoder();

const basisKey = await crypto.subtle.importKey(
  'raw', enc.encode('Passwort123'), 'PBKDF2', false, ['deriveKey']
);

const hmacKey = await crypto.subtle.deriveKey(
  { name: 'PBKDF2', salt: crypto.getRandomValues(new Uint8Array(16)), iterations: 310000, hash: 'SHA-256' },
  basisKey,
  { name: 'HMAC', hash: 'SHA-512', length: 512 }, // HmacImportParams
  false,
  ['sign', 'verify']
);

console.log(hmacKey.algorithm.hash.name, hmacKey.algorithm.length);
SHA-512 512

// Wichtig · Fallstricke

  • Nur in sicheren Kontexten: crypto.subtle gibt es ausschließlich unter HTTPS oder localhost. Sonst ist es undefined.
  • length wird in Bit angegeben, nicht in Byte. Passt die Angabe nicht zum Schlüsselmaterial, wirft importKey() einen DataError. Am einfachsten lässt du length beim Import weg.
  • Wenn hash fehlt oder falsch geschrieben ist (z. B. \"SHA256\" ohne Bindestrich), folgt ein TypeError bzw. NotSupportedError.
  • Beim Import im Format \"jwk\" muss das Feld alg (z. B. HS256) zu hash passen. Sonst gibt es einen DataError.
  • Sicherheit: Prüfe Signaturen mit crypto.subtle.verify() und nicht per String-Vergleich (===). Ein einfacher Vergleich ist anfällig für Timing-Angriffe. Setze extractable auf false, solange du den Schlüssel nicht exportieren musst. Vermeide SHA-1 bei neuen Anwendungen.
  • In Node.js ist die API über globalThis.crypto.subtle (ab v19) bzw. require('node:crypto').webcrypto.subtle (ab v15) verfügbar.