Mensagem de erro
Invalid key object type public, expected private.
Os dois tipos citados mudam conforme a chave e a operação: sign() com uma chave secreta informa “Invalid key object type secret, expected private.”, e verify() com uma chave secreta, “Invalid key object type secret, expected private or public.” O próprio verify() aceita uma chave privada e verifica com a metade pública dela. A estrutura da mensagem é estável.
Node.js crypto — TypeError, code ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE
O que significa
Você passou um KeyObject da classe errada para a operação: crypto.sign() precisa de uma chave privada, mas recebeu uma pública (ou verify() recebeu uma chave secreta etc.). Os objetos de chave do Node conhecem o próprio tipo — público, privado ou secreto — e cada API aceita apenas tipos específicos.
Por que acontece
Variáveis trocadas no ponto de chamada
comumpublicKey e privateKey trocadas em uma desestruturação, ou um parâmetro de função chamado key que recebe qualquer uma que o chamador tinha em mãos. Assinar com a chave pública é impossível por definição, e o Node avisa isso logo, em vez de falhar de forma misteriosa mais tarde.
O carregamento gerou um tipo diferente do que se supunha
comumcreatePublicKey(privatePem) deriva uma chave pública de propósito — o código que depois trata o resultado como chave privada para assinar falha aqui. Da mesma forma, um arquivo PEM que na verdade contém uma chave pública é carregado com o tipo "public", não importa o que diga o nome do arquivo.
Chave secreta (simétrica) em uma API assimétrica
ocasionalA saída de createSecretKey() (uma chave HMAC/AES) passada para sign/verify com ECDSA. Material simétrico não pode participar de assinaturas de chave pública.
Como corrigir
- 1.
Validar os tipos de chave na fronteira
KeyObject.type é "public" | "private" | "secret". Uma asserção de uma linha transforma um erro criptográfico confuso em um erro óbvio, já no carregamento.
js import { createPrivateKey } from "node:crypto"; const signingKey = createPrivateKey(pem); if (signingKey.type !== "private") { throw new Error(`expected private key, got ${signingKey.type}`); } - 2.
Usar cada metade do par na operação que lhe cabe
A privada assina, a pública verifica. Se você só tem a chave privada, derive dela a metade pública para a verificação, em vez de reutilizar o objeto privado em todo lugar.
js import { createPublicKey, sign, verify } from "node:crypto"; const signature = sign("sha256", data, privateKey); // private → sign const publicKey = createPublicKey(privateKey); // derive public half const ok = verify("sha256", data, publicKey, signature); // public → verify