Message d’erreur
InvalidAccessError: Failed to execute 'exportKey' on 'SubtleCrypto': key is not extractable
Également affiché sous la forme
- InvalidAccessError: The CryptoKey is nonextractable
- InvalidAccessError: A parameter or an operation is not supported by the underlying object
Le texte ci-dessus est celui de Chromium ; Safari/WebKit : « The CryptoKey is nonextractable » ; Firefox : « A parameter or an operation is not supported by the underlying object ». Ce sont toutes des DOMException `InvalidAccessError`.
WebCrypto SubtleCrypto.exportKey / wrapKey — DOMException InvalidAccessError (Chromium / Firefox / WebKit)
Ce que cela signifie
La clé a été créée avec `extractable: false` : son contenu ne peut donc jamais être relu, ni par `exportKey`, ni par `wrapKey`. C’est tout l’intérêt de cet indicateur : la clé privée reste dans l’implémentation cryptographique du navigateur, et les scripts (y compris les scripts injectés) peuvent l’utiliser, mais pas la voler. Les clés publiques d’une paire générée sont toujours exportables ; cette erreur concerne les clés privées et les clés secrètes.
Pourquoi cela se produit
La clé a volontairement été générée non extractible
fréquenteLes bibliothèques et les conceptions inspirées des clés d’accès créent ainsi des clés liées à l’appareil. Une fonctionnalité ajoutée plus tard, qui veut afficher, sauvegarder ou synchroniser la clé privée, se heurte à ce choix.
Une clé restaurée depuis IndexedDB conserve son indicateur
occasionnelleLes CryptoKey stockées dans IndexedDB reviennent exactement telles qu’elles ont été créées ; il est impossible de les rendre exportables après coup.
Valeur par défaut d’une bibliothèque
occasionnelleCertaines bibliothèques JOSE et E2E génèrent par défaut des clés avec `extractable: false` ; leurs fonctions d’exportation échouent alors pour les clés privées.
Comment corriger l’erreur
- 1.
Garder la clé privée sous forme d’objet, exporter la clé publique
Stockez les clés non extractibles sous forme d’objets `CryptoKey` dans IndexedDB et ne partagez que la clé publique (SPKI ou JWK). Vous conservez ainsi la protection qu’apporte l’indicateur.
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.
Ne créer des clés extractibles que lorsque l’exportation est une exigence
Si la clé privée doit réellement quitter le navigateur, générez-la extractible et ne l’exportez qu’enveloppée par une autre clé.
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 });