Mensagem de erro
Failed to read asymmetric key
Node.js crypto — e.g. code ERR_OSSL_ASN1_WRONG_TAG
O que significa
createPublicKey() — ou qualquer chamada que receba uma chave pública em DER, como crypto.verify() — recebeu bytes cuja estrutura ASN.1 não corresponde ao tipo que você declarou, por exemplo, type: "spki" quando os bytes são, na verdade, uma chave privada EC SEC1. O OpenSSL interpretou o suficiente para saber que as tags estão erradas e parou. (createPrivateKey() e PEMs com rótulo errado relatam o mesmo tipo de divergência com as palavras do próprio OpenSSL, como “error:068000A8:asn1 encoding routines::wrong tag”.) O código que acompanha o erro (ERR_OSSL_ASN1_WRONG_TAG e afins) indica a divergência no nível do ASN.1. Ao contrário do erro “unsupported” das rotinas DECODER, que significa que nada interpretável foi encontrado, este indica que os bytes tinham uma estrutura reconhecível, só que errada para o tipo declarado.
Por que acontece
O tipo declarado não corresponde aos bytes
comumO mundo DER tem vários contêineres: SPKI para chaves públicas, PKCS#8 para chaves privadas, SEC1 para chaves privadas EC legadas, PKCS#1 para RSA legado. Declarar type: "spki" para uma chave privada SEC1 ou PKCS#8, ou para um certificado inteiro, faz a verificação de tags falhar na hora.
Base64 não decodificado ou decodificado duas vezes
comumPassar texto base64 com format: "der" (e o OpenSSL interpreta ASCII como ASN.1) ou aplicar Buffer.from(pem, "base64") a um PEM completo, com as linhas de cabeçalho, produz nos dois casos uma sopa de bytes com tags erradas.
Um ponto EC bruto em vez de uma estrutura de chave
ocasionalOs 65 bytes de um ponto não comprimido (0x04‖X‖Y) não são DER — são o payload que fica dentro de um SPKI. Passá-los diretamente para createPublicKey falha; é preciso encapsulá-los ou importá-los via JWK ou pela importação raw da WebCrypto.
Como corrigir
- 1.
Identificar a estrutura e declará-la corretamente
O asn1parse imprime a estrutura externa. Um SPKI começa com uma SEQUENCE que contém um AlgorithmIdentifier; um PKCS#8 começa com um INTEGER 0 de versão; chaves EC SEC1, com INTEGER 1.
bash openssl asn1parse -inform der -in key.der | head -5 - 2.
Ajustar as opções do Node ao contêiner
Depois que você conhece o contêiner, o mapeamento é mecânico.
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.
Converter contêineres legados uma única vez, na fronteira do sistema
Padronize o armazenamento em PKCS#8/SPKI para que o código da aplicação nunca precise adivinhar.
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