Fehlermeldung
TypeError: Failed to execute 'sign' on 'SubtleCrypto': EcdsaParams: hash: Missing or not an AlgorithmIdentifier
Auch ausgegeben als
- TypeError: Failed to execute 'verify' on 'SubtleCrypto': EcdsaParams: hash: Missing or not an AlgorithmIdentifier
- TypeError: Member EcdsaParams.hash is required and must be an instance of (object or DOMString)
- NotSupportedError: Failed to execute 'sign' on 'SubtleCrypto': EcdsaParams: hash: Algorithm: Unrecognized name
Oben steht der Text von Chromium (bei `verify` ändert sich der Methodenname); Safari/WebKit: „Member EcdsaParams.hash is required and must be an instance of (object or DOMString)“; Firefox meldet einen generischen `SyntaxError` („An invalid or illegal string was specified“).
WebCrypto SubtleCrypto.sign / verify with ECDSA — algorithm parameter without hash (Chromium / WebKit)
Was der Fehler bedeutet
ECDSA erhält in WebCrypto die Hashfunktion pro Operation, nicht pro Schlüssel: `sign` und `verify` brauchen `{ name: "ECDSA", hash: "SHA-256" }`. Der Aufruf hat ein Algorithmusobjekt ohne `hash` übergeben – meist das Objekt `{ name, namedCurve }` aus der Schlüsselgenerierung –, deshalb hat der Browser die Parameter vor dem Signieren abgelehnt. (Bei RSA-Schlüsseln ist es umgekehrt: Dort wird der Hash beim Import festgelegt.) Ein falsch geschriebener Hash wie `"SHA256"` scheitert stattdessen mit einem `NotSupportedError` wegen eines unbekannten Namens.
Warum der Fehler auftritt
Parameter der Schlüsselgenerierung für sign/verify wiederverwendet
häufigEine einzige Konstante `ALG = { name: "ECDSA", namedCurve: "P-256" }` zu speichern und überall zu übergeben, funktioniert für `generateKey` und `importKey`, aber `sign` braucht `hash`.
Hash-Name in JOSE- oder OpenSSL-Schreibweise
häufigDie Namen in WebCrypto lauten `SHA-256`, `SHA-384`, `SHA-512` (mit Bindestrich). `SHA256`, `sha256` ohne Bindestrich oder `ES256` werden nicht erkannt.
Erwartung, dass der Schlüssel den Hash mitführt
gelegentlichCode, der von RSA portiert wurde (Schlüssel vom Typ `RSASSA-PKCS1-v1_5` haben `hash` in ihren Importparametern), nimmt an, dass das auch für ECDSA-Schlüssel gilt; das stimmt nicht.
So behebst du den Fehler
- 1.
Schlüsselparameter und Operationsparameter trennen
Definiere ein Objekt für die Schlüsselerzeugung und eines für das Signieren. Für JWT mit ES256/ES384/ES512 verwende jeweils SHA-256/384/512 mit P-256/384/521.
js const KEY_ALG = { name: "ECDSA", namedCurve: "P-256" }; // generateKey / importKey const SIGN_ALG = { name: "ECDSA", hash: "SHA-256" }; // sign / verify (ES256) const pair = await crypto.subtle.generateKey(KEY_ALG, false, ["sign", "verify"]); const signature = await crypto.subtle.sign(SIGN_ALG, pair.privateKey, data); // 64 bytes, raw r||s const ok = await crypto.subtle.verify(SIGN_ALG, pair.publicKey, signature, data);