crypto.subtle est l’interface cryptographique standard de la plateforme web. Les mêmes appels (generateKey, importKey, sign, verify, exportKey) fonctionnent dans Chromium, Firefox et WebKit ainsi que dans les environnements d’exécution serveur comme Node.js, ce qui en fait le choix naturel pour du code qui doit tourner des deux côtés. Elle n’existe que dans les contextes sécurisés : sur une page en simple http, crypto.subtle vaut undefined.
La spécification impose le format r‖s brut pour les signatures ECDSA, soit 64 octets sur P-256, et la vérification a trouvé exactement cela dans les quatre moteurs. Ce format correspond à JWS et à JWT, si bien que les jetons ES256 n’ont besoin d’aucune conversion, mais pas à OpenSSL, au SHA256withECDSA de Java, au SignASN1 de Go ni à node:crypto, qui utilisent tous ASN.1 DER. Comme une signature DER passée à verify() renvoie un simple false plutôt qu’une erreur, l’incompatibilité ressemble à une falsification ; convertissez avec le convertisseur DER ⇄ brut ou testez les deux formes dans le vérificateur de signatures.
Les clés sont l’autre source fréquente de friction. importKey("spki") prend des octets DER, jamais du texte PEM ; "raw" prend le point SEC1, et la forme compressée est acceptée par Node.js, Chromium et Firefox mais refusée par WebKit : pour du code portable, envoyez donc le point non compressé. Les clés privées ne s’importent qu’en PKCS#8 DER ou en JWK ; les fichiers SEC1 EC PRIVATE KEY qu’OpenSSL écrit par défaut doivent d’abord être convertis en PKCS#8, par exemple avec le convertisseur JWK.
La liste des courbes s’arrête à P-256, P-384 et P-521 : secp256k1 et Brainpool lèvent NotSupportedError partout, si bien que les clés Bitcoin et Ethereum exigent une bibliothèque comme @noble/curves. Ed25519 fonctionne dans les quatre moteurs, Ed448 uniquement dans Node.js. La prise en charge post-quantique est inégale : Node.js 24.22 implémente ML-DSA et ML-KEM derrière un avertissement de fonctionnalité expérimentale, Chromium 156 accepte ML-DSA et ML-KEM-768/1024 mais pas ML-KEM-512, et Firefox 157 et WebKit 27.2 n’ont ni l’un ni l’autre. Détectez leur disponibilité avant de vous y fier, et essayez les algorithmes dans le bac à sable des signatures post-quantiques.
L’exemple montre l’approche portable : nommer la fonction de hachage dans l’objet algorithme, importer les clés PEM externes après leur décodage en DER, et ne pas oublier que la sortie de 64 octets doit être convertie en DER avant qu’un vérificateur de type OpenSSL puisse la lire.