Mensaje de error
TypeError: Failed to execute 'importKey' on 'SubtleCrypto': The provided value is not of type '(ArrayBuffer or ArrayBufferView or JsonWebKey)'.
También se muestra como
- TypeError: SubtleCrypto.importKey: Argument 2 is not an object.
- TypeError: Type error
Arriba está el texto de Chromium; Firefox dice «SubtleCrypto.importKey: Argument 2 is not an object.», y Safari/WebKit, solo «Type error». Node.js informa de `ERR_INVALID_ARG_TYPE` con la misma llamada.
WebCrypto SubtleCrypto.importKey — PEM text passed as keyData (Chromium / Firefox / WebKit)
Qué significa
`importKey` recibió una cadena como `keyData`. WebCrypto nunca analiza texto: para `"spki"`, `"pkcs8"` y `"raw"` espera DER binario (un `ArrayBuffer` o un array tipado), y para `"jwk"`, un objeto de JavaScript. El navegador rechaza la llamada durante la conversión de los argumentos, antes de mirar el formato o la clave, así que el PEM puede ser perfectamente válido.
Por qué ocurre
Una cadena PEM pasada directamente
frecuenteEl texto `-----BEGIN PUBLIC KEY-----` que llega de un servidor, de un archivo de configuración o de la documentación de una biblioteca JWT. Primero hay que decodificarlo de base64 a DER.
Texto Base64 en lugar de bytes
frecuenteIncluso sin las líneas de armadura, una cadena base64 sigue siendo una cadena. Decodifícala a bytes con `atob` (o con `Uint8Array.fromBase64` donde esté disponible).
Una JWK como texto JSON
ocasionalCon el formato `"jwk"`, el texto generado con `JSON.stringify` falla de la misma forma; pasa el objeto ya analizado.
Cómo solucionarlo
- 1.
Quitar la armadura y decodificar a bytes
Quita las líneas BEGIN/END y los espacios en blanco, decodifica de base64 y elige el formato según la etiqueta: `PUBLIC KEY` → `spki`, `PRIVATE KEY` → `pkcs8`.
js function pemToDer(pem) { const base64 = pem.replace(/-----(BEGIN|END) [A-Z ]+-----/g, "").replace(/\s+/g, ""); return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)); } const publicKey = await crypto.subtle.importKey( "spki", pemToDer(publicKeyPem), // "PUBLIC KEY" -> spki, "PRIVATE KEY" -> pkcs8 { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"], ); - 2.
Pasar las JWK como objetos
Los endpoints JWKS ya entregan objetos; analiza el texto JSON una sola vez y pasa el objeto con la curva correspondiente.
js const jwk = JSON.parse(jwkText); // an object, not the JSON string const key = await crypto.subtle.importKey("jwk", jwk, { name: "ECDSA", namedCurve: jwk.crv }, false, ["verify"]);