Aller au contenu
ecdsa.com
WebCrypto crypto.subtleWebCrypto

Message d’erreur

OperationError: The operation failed for an operation-specific reason

WebCrypto crypto.subtle — browsers & Node

Ce que cela signifie

L’erreur générique de WebCrypto, volontairement vague : la primitive elle-même a échoué. Pour decrypt() avec AES-GCM, cela signifie que la vérification du tag d’authentification a échoué (mauvaise clé, mauvais IV, mauvaises données additionnelles ou texte chiffré modifié). La spécification garde un message générique pour que les implémentations ne révèlent pas pourquoi un contrôle cryptographique a échoué. Pour sign() et deriveBits(), le même nom couvre les échecs internes de la primitive : l’opération qui figure dans votre trace de pile compte donc davantage que le texte du message.

Pourquoi cela se produit

Comment corriger l’erreur

  1. 1.

    Transmettre l’IV et le texte chiffré ensemble, décoder de façon symétrique

    Placez l’IV devant le texte chiffré et séparez-les au déchiffrement, pour que les deux côtés soient toujours d’accord ; utilisez la même variante de base64 partout.

    js
    // encrypt
    const iv = crypto.getRandomValues(new Uint8Array(12));
    const ct = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, data);
    const packed = new Uint8Array([...iv, ...new Uint8Array(ct)]);
    
    // decrypt
    const buf = packedFromWire;
    const pt = await crypto.subtle.decrypt(
      { name: "AES-GCM", iv: buf.slice(0, 12) }, key, buf.slice(12),
    );
  2. 2.

    Le traiter comme un verdict d’intégrité, pas comme une corruption

    Lorsque decrypt lève une OperationError, la réponse correcte est « ce texte chiffré n’est pas authentique avec cette clé » : rejetez-le. Ne réessayez pas en ajustant le remplissage et ne vous rabattez pas sur des modes non authentifiés ; l’échec de la vérification est précisément la fonction de sécurité.

  3. 3.

    Comparer les empreintes des clés des deux côtés

    Exportez les deux clés et hachez-les ; des condensats différents lèvent le mystère en une seule étape.

    js
    const raw = await crypto.subtle.exportKey("raw", key);
    const fp = await crypto.subtle.digest("SHA-256", raw);
    console.log(Buffer.from(fp).toString("hex").slice(0, 16)); // compare on both sides

Erreurs associées

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