Mensaje de error
DataError: Data provided to an operation does not meet requirements
Lo que hay que comprobar es el nombre de la DOMException, DataError; el texto del mensaje varía según el entorno de ejecución. Firefox y Safari muestran la frase genérica de arriba; Chrome a menudo deja el mensaje vacío o indica el motivo («The imported EC key specifies a different curve than requested»); Node imprime «Invalid keyData» o un motivo concreto, como «Named curve mismatch».
WebCrypto crypto.subtle.importKey — browsers & Node
Qué significa
importKey (o unwrapKey) rechazó los bytes de la clave: no se pueden analizar en el formato declarado o su contenido contradice los parámetros del algoritmo (curva incorrecta, campos JWK que no concuerdan). Es el equivalente en WebCrypto de «estos bytes no son la clave que dices que son», y se lanza antes de que se cree ningún objeto de clave.
Por qué ocurre
El nombre del formato no corresponde a los bytes
frecuenteImportar una clave pública con el formato "pkcs8" (contenedor de clave privada) o una clave privada con "spki" es la confusión clásica. Los nombres no son intuitivos: spki = pública, pkcs8 = privada, raw = punto EC sin envolver, jwk = objeto JSON.
El texto PEM no se convirtió a binario
frecuenteimportKey recibe un ArrayBuffer con DER, no texto PEM. Pasar la cadena PEM codificada como UTF-8 —o decodificarla de base64 sin quitar antes las líneas BEGIN/END y los saltos de línea— produce bytes que no superan el análisis estructural.
Discrepancia de curva entre la clave y el algoritmo
ocasionalUn SPKI P-256 importado con namedCurve: "P-384" (Node notifica «Named curve mismatch»), o una JWK cuyo crv no concuerda con el algoritmo solicitado. Los bytes están bien; lo que está mal es la declaración. Firefox no comprueba el caso SPKI al importar, así que el mismo código puede pasar ahí y fallar en Chrome, Safari y Node.
Punto en bruto no válido
ocasionalCon el formato "raw", los 65 bytes deben ser 0x04 ‖ X ‖ Y con (X, Y) realmente sobre la curva; Chrome, Firefox y Node rechazan un punto dañado al importarlo, mientras que el motor de Safari lo importó sin quejarse en nuestra prueba. Los puntos comprimidos (33 bytes con el prefijo 0x02/0x03) son una trampa de portabilidad en sentido contrario: Chrome, Firefox y Node los aceptan, y Safari los rechaza con este error.
Cómo solucionarlo
- 1.
Convertir correctamente PEM → ArrayBuffer
Quita las líneas de armadura, decodifica el cuerpo de base64 y elige el formato según la etiqueta PEM: PUBLIC KEY → spki, PRIVATE KEY → pkcs8.
js function pemToArrayBuffer(pem) { const b64 = pem.replace(/-----[^-]+-----/g, "").replace(/\s+/g, ""); return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)).buffer; } const key = await crypto.subtle.importKey( "spki", pemToArrayBuffer(publicKeyPem), { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"], ); - 2.
Preferir JWK cuando tienes material de clave en JSON
Los endpoints JWKS ya sirven objetos listos para WebCrypto: sin conversión binaria, y crv viaja con la clave.
js const key = await crypto.subtle.importKey( "jwk", jwk, { name: "ECDSA", namedCurve: jwk.crv }, false, ["verify"], ); - 3.
Confirmar qué son realmente los bytes
Pega la clave en el decodificador de certificados o en el verificador de firmas de abajo: ambos analizan SPKI/PKCS#8/JWK localmente e indican la curva y el tipo de clave reales, lo que suele revelar la discrepancia de inmediato.