Skip to content
ecdsa.com
WebCrypto SubtleCrypto.sign / verify with ECDSAWebCrypto

Error message

TypeError: Failed to execute 'sign' on 'SubtleCrypto': EcdsaParams: hash: Missing or not an AlgorithmIdentifier

Also printed as

  • 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

Chromium's text is above (for `verify` the method name changes); Safari/WebKit: "Member EcdsaParams.hash is required and must be an instance of (object or DOMString)"; Firefox reports a generic `SyntaxError` ("An invalid or illegal string was specified").

WebCrypto SubtleCrypto.sign / verify with ECDSA — algorithm parameter without hash (Chromium / WebKit)

What it means

ECDSA in WebCrypto takes the hash function per operation, not per key: `sign` and `verify` need `{ name: "ECDSA", hash: "SHA-256" }`. The call passed an algorithm object without `hash` — usually the `{ name, namedCurve }` object from key generation — so the browser rejected the parameters before signing. (RSA keys are the opposite: their hash is fixed at import time.) A misspelled hash such as `"SHA256"` fails with a `NotSupportedError` about an unrecognized name instead.

Why it happens

How to fix it

  1. 1.

    Keep key parameters and operation parameters separate

    Define one object for key creation and one for signing. For JWT ES256/ES384/ES512, use SHA-256/384/512 with P-256/384/521 respectively.

    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);

Related errors

Browse the full signature error database