Mensagem de erro
DataError: Data provided to an operation does not meet requirements
O que deve ser comparado é o nome da DOMException, DataError; o texto da mensagem varia conforme o runtime. O Firefox e o Safari mostram a frase genérica acima; o Chrome muitas vezes deixa a mensagem vazia ou cita o motivo (“The imported EC key specifies a different curve than requested”); o Node imprime “Invalid keyData” ou um motivo específico, como “Named curve mismatch”.
WebCrypto crypto.subtle.importKey — browsers & Node
O que significa
O importKey (ou o unwrapKey) rejeitou os bytes da chave: eles não são reconhecidos no formato que você declarou, ou o conteúdo deles contradiz os parâmetros do algoritmo (curva errada, campos da JWK incompatíveis). É o equivalente, no WebCrypto, a “estes bytes não são a chave que você diz que são” — lançado antes de qualquer objeto de chave ser criado.
Por que acontece
O nome do formato não corresponde aos bytes
comumImportar uma chave pública com o formato “pkcs8” (contêiner de chave privada) ou uma chave privada com “spki” é a troca clássica. Os nomes não são intuitivos: spki = pública, pkcs8 = privada, raw = ponto EC puro, jwk = objeto JSON.
O texto PEM não foi convertido em binário
comumO importKey recebe um ArrayBuffer de DER, não texto PEM. Passar a string PEM codificada em UTF-8 — ou decodificá-la de base64 sem antes remover as linhas BEGIN/END e as quebras de linha — produz bytes que falham na análise estrutural.
Curva divergente entre a chave e o algoritmo
ocasionalUm SPKI P-256 importado com namedCurve: "P-384" (o Node informa “Named curve mismatch”), ou uma JWK cujo crv não condiz com o algoritmo solicitado. Os bytes estão certos; a declaração é que está errada. O Firefox não verifica o caso do SPKI no momento da importação, então o mesmo código pode passar nele e falhar no Chrome, no Safari e no Node.
Ponto inválido no formato raw
ocasionalNo formato “raw”, os 65 bytes precisam ser 0x04 ‖ X ‖ Y, com (X, Y) de fato na curva; o Chrome, o Firefox e o Node rejeitam um ponto corrompido na importação, enquanto o motor do Safari o importou sem reclamar no nosso teste. Pontos comprimidos (33 bytes com prefixo 0x02/0x03) são uma armadilha de portabilidade no sentido inverso: o Chrome, o Firefox e o Node os aceitam, e o Safari os rejeita com este erro.
Como corrigir
- 1.
Converter PEM → ArrayBuffer corretamente
Remova as linhas do envelope PEM, decodifique o corpo de base64 e escolha o formato pelo rótulo 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 quando o material de chave estiver em JSON
Endpoints JWKS já servem objetos prontos para o WebCrypto — sem conversão binária, e o crv vai junto com a chave.
js const key = await crypto.subtle.importKey( "jwk", jwk, { name: "ECDSA", namedCurve: jwk.crv }, false, ["verify"], ); - 3.
Confirmar o que os bytes realmente são
Cole a chave no decodificador de certificados ou no verificador de assinaturas abaixo — os dois analisam SPKI/PKCS#8/JWK localmente e informam a curva e o tipo de chave reais, o que costuma apontar a divergência na hora.