Zum Inhalt springen
ecdsa.com
WebCrypto SubtleCrypto.exportKey / wrapKeyWebCrypto

Fehlermeldung

InvalidAccessError: Failed to execute 'exportKey' on 'SubtleCrypto': key is not extractable

Auch ausgegeben als

  • InvalidAccessError: The CryptoKey is nonextractable
  • InvalidAccessError: A parameter or an operation is not supported by the underlying object

Oben steht der Text von Chromium; Safari/WebKit: „The CryptoKey is nonextractable“; Firefox: „A parameter or an operation is not supported by the underlying object“. Alle sind DOMExceptions vom Typ `InvalidAccessError`.

WebCrypto SubtleCrypto.exportKey / wrapKey — DOMException InvalidAccessError (Chromium / Firefox / WebKit)

Was der Fehler bedeutet

Der Schlüssel wurde mit `extractable: false` erzeugt, deshalb lässt sich sein Schlüsselmaterial nie wieder auslesen – weder mit `exportKey` noch mit `wrapKey`. Genau dafür ist das Flag da: Der private Schlüssel bleibt in der Krypto-Implementierung des Browsers, und Skripte (auch eingeschleuste) können ihn verwenden, aber nicht stehlen. Der öffentliche Schlüssel eines erzeugten Paars ist immer exportierbar; dieser Fehler betrifft private und geheime Schlüssel.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Privaten Schlüssel als Objekt behalten, öffentlichen Schlüssel exportieren

    Speichere nicht extrahierbare Schlüssel als Objekte vom Typ `CryptoKey` in IndexedDB und gib nur den öffentlichen Schlüssel weiter (SPKI oder JWK). So bleibt der Schutz erhalten, den das Flag bietet.

    js
    const pair = await crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, false, ["sign", "verify"]);
    // Persist the non-extractable private key as a CryptoKey object (structured clone), never as bytes:
    await idbPut("signing-key", pair.privateKey);
    // Share only the public key:
    const jwk = await crypto.subtle.exportKey("jwk", pair.publicKey);
  2. 2.

    Extrahierbare Schlüssel nur erzeugen, wenn der Export zwingend nötig ist

    Muss der private Schlüssel wirklich den Browser verlassen, erzeuge ihn als extrahierbar und exportiere ihn ausschließlich mit einem anderen Schlüssel verpackt.

    js
    // Only if the private key must leave the browser (e.g. a user-initiated, encrypted backup):
    const pair = await crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, true, ["sign", "verify"]);
    const wrapped = await crypto.subtle.wrapKey("pkcs8", pair.privateKey, backupKey, { name: "AES-GCM", iv });

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen