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
Der Schlüssel wurde absichtlich als nicht extrahierbar erzeugt
häufigBibliotheken und Passkey-ähnliche Ansätze erzeugen gerätegebundene Schlüssel auf diese Weise. Eine spätere Funktion, die den privaten Schlüssel anzeigen, sichern oder synchronisieren soll, kollidiert mit dieser Entscheidung.
Ein aus IndexedDB wiederhergestellter Schlüssel behält sein Flag
gelegentlichIn IndexedDB gespeicherte CryptoKeys kommen genau so zurück, wie sie erzeugt wurden; sie nachträglich exportierbar zu machen, ist unmöglich.
Die Voreinstellung einer Bibliothek
gelegentlichManche JOSE- und E2E-Bibliotheken erzeugen Schlüssel standardmäßig mit `extractable: false`; ihre Export-Hilfsfunktionen scheitern dann bei privaten Schlüsseln.
So behebst du den Fehler
- 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.
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 });