Mensaje de error
Failed to read asymmetric key
Node.js crypto — e.g. code ERR_OSSL_ASN1_WRONG_TAG
Qué significa
createPublicKey() —o cualquier llamada que reciba una clave pública en DER, como crypto.verify()— recibió bytes cuya estructura ASN.1 no coincide con el tipo declarado; por ejemplo, type: "spki" cuando los bytes son en realidad una clave privada EC SEC1. OpenSSL analizó lo suficiente para saber que las etiquetas son incorrectas y se detuvo. (createPrivateKey() y los PEM mal etiquetados notifican el mismo tipo de discrepancia con las propias palabras de OpenSSL, como «error:068000A8:asn1 encoding routines::wrong tag».) El código que lo acompaña (ERR_OSSL_ASN1_WRONG_TAG y similares) nombra la discrepancia a nivel ASN.1. A diferencia del error «unsupported» del decodificador (DECODER routines), que significa que no se encontró nada analizable, este indica que los bytes tenían una estructura reconocible, pero equivocada para el tipo declarado.
Por qué ocurre
El tipo declarado no coincide con los bytes
frecuenteEn DER hay varios contenedores: SPKI para claves públicas, PKCS#8 para claves privadas, SEC1 para las claves privadas EC heredadas y PKCS#1 para las RSA heredadas. Declarar type: "spki" para una clave privada SEC1 o PKCS#8, o para un certificado completo, hace saltar de inmediato la comprobación de etiquetas.
Base64 sin decodificar o decodificado dos veces
frecuentePasar texto base64 con format: "der" (de modo que OpenSSL analiza ASCII como ASN.1) o aplicar Buffer.from(pem, "base64") a un PEM completo con sus líneas de encabezado: ambas cosas producen una sopa de bytes con etiquetas incorrectas.
Un punto EC en bruto en lugar de una estructura de clave
ocasionalLos 65 bytes de un punto sin comprimir (0x04‖X‖Y) no son DER: son la carga útil que va dentro de un SPKI. Pasarlos directamente a createPublicKey falla; hay que envolverlos o importarlos como JWK o mediante la importación raw de WebCrypto.
Cómo solucionarlo
- 1.
Identificar la estructura y declararla tal como es
asn1parse imprime la estructura exterior. Un SPKI empieza con una SEQUENCE que contiene un AlgorithmIdentifier; PKCS#8 empieza con un INTEGER 0 de versión, y las claves EC SEC1, con INTEGER 1.
bash openssl asn1parse -inform der -in key.der | head -5 - 2.
Ajustar las opciones de Node al contenedor
Una vez que conoces el contenedor, la correspondencia es mecánica.
js // SPKI public key createPublicKey({ key: der, format: "der", type: "spki" }); // PKCS#8 private key createPrivateKey({ key: der, format: "der", type: "pkcs8" }); // SEC1 (BEGIN EC PRIVATE KEY) private key createPrivateKey({ key: der, format: "der", type: "sec1" }); - 3.
Convertir los contenedores heredados una sola vez, en el punto de entrada
Usa siempre PKCS#8/SPKI en el almacenamiento para que el código de la aplicación nunca tenga que adivinar.
bash openssl pkey -in legacy-ec.pem -out key-pkcs8.pem # any private → PKCS#8 openssl pkey -in key-pkcs8.pem -pubout -out pub-spki.pem # derive SPKI public