本文へスキップ
ecdsa.com
Node.js cryptoNode.js の crypto

エラーメッセージ

Invalid key object type public, expected private.

2 つの名詞は、鍵と操作に応じて入れ替わります。共通鍵で sign() を呼ぶと「Invalid key object type secret, expected private.」、共通鍵で verify() を呼ぶと「Invalid key object type secret, expected private or public.」になります。verify() 自体は秘密鍵も受け付け、それに対応する公開鍵で検証します。メッセージの構造は変わりません。

Node.js crypto — TypeError, code ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE

このエラーの意味

操作に合わない種類の KeyObject を渡しています。crypto.sign() には秘密鍵が必要なのに公開鍵を受け取った(あるいは verify() が共通鍵を受け取った)といったケースです。Node の鍵オブジェクトは自身の種類(公開鍵、秘密鍵、共通鍵のいずれか)を把握しており、各 API は特定の種類しか受け付けません。

発生する理由

修正方法

  1. 1.

    境界で鍵の種類をアサートする

    KeyObject.type は "public" | "private" | "secret" のいずれかです。1 行のアサーションを入れるだけで、わかりにくい暗号エラーが、読み込み時のわかりやすいエラーに変わります。

    js
    import { createPrivateKey } from "node:crypto";
    
    const signingKey = createPrivateKey(pem);
    if (signingKey.type !== "private") {
      throw new Error(`expected private key, got ${signingKey.type}`);
    }
  2. 2.

    鍵ペアのそれぞれを本来の操作に使う

    秘密鍵で署名し、公開鍵で検証します。秘密鍵しか持っていない場合は、秘密鍵のオブジェクトをあらゆる箇所で使い回すのではなく、検証用に公開鍵を導出してください。

    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

関連するエラー

署名エラーデータベースをすべて見る