Aller au contenu
ecdsa.com
WebCrypto SubtleCrypto.exportKey / wrapKeyWebCrypto

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

Comment corriger l’erreur

  1. 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. 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 });

Erreurs associées

Parcourir toute la base de données des erreurs de signature