Mensaje de error
Invalid key object type public, expected private.
Los dos sustantivos cambian según la clave y la operación: sign() con una clave secreta da «Invalid key object type secret, expected private.», y verify() con una clave secreta, «Invalid key object type secret, expected private or public.». verify() en sí acepta una clave privada y verifica con su mitad pública. La estructura del mensaje es estable.
Node.js crypto — TypeError, code ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE
Qué significa
Se pasó un KeyObject de una clase incorrecta para la operación: crypto.sign() necesita una clave privada pero recibió una pública (o verify() recibió una clave secreta, etc.). Los objetos de clave de Node conocen su propio tipo —pública, privada o secreta— y cada API solo acepta tipos concretos.
Por qué ocurre
Variables intercambiadas en el punto de llamada
frecuentepublicKey y privateKey intercambiadas en una desestructuración, o un parámetro de función llamado key que recibe la que tuviera a mano quien llama. Firmar con la clave pública es imposible por construcción, y Node lo dice en lugar de fallar de forma misteriosa más adelante.
La carga produjo un tipo distinto del supuesto
frecuentecreatePublicKey(privatePem) deriva intencionadamente una clave pública; el código que después trata el resultado como una clave privada para firmar falla aquí. Del mismo modo, un archivo PEM que en realidad contiene una clave pública se carga con el tipo «public», diga lo que diga el nombre del archivo.
Clave secreta (simétrica) en una API asimétrica
ocasionalLa salida de createSecretKey() (una clave HMAC/AES) pasada a sign/verify para ECDSA. El material simétrico no puede participar en firmas de clave pública.
Cómo solucionarlo
- 1.
Comprobar los tipos de clave en el punto de entrada
KeyObject.type es "public" | "private" | "secret". Una aserción de una línea convierte un error criptográfico confuso en uno evidente en el momento de la carga.
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 mitad del par para su propia operación
La privada firma, la pública verifica. Si solo tienes una clave privada, deriva de ella la mitad pública para la verificación en lugar de reutilizar el objeto privado en todas partes.
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