エラーメッセージ
error:1E08010C:DECODER routines::unsupported
Node 26 / OpenSSL 3.x で再現しました。OpenSSL の CLI は長い形式「error:1E08010C:DECODER routines:OSSL_DECODER_from_bio:unsupported」を出力します。Node 16 以前(OpenSSL 1.1.1)では、同じミスで別のメッセージが出ていました。
Node.js crypto (OpenSSL 3) — code ERR_OSSL_UNSUPPORTED
このエラーの意味
createPrivateKey()、createPublicKey()、sign()、verify() に渡した鍵データを、OpenSSL 3 のデコーダーが解析できませんでした。「unsupported」という語が含まれていても、アルゴリズムが存在しないことが原因である場合はほとんどありません。デコーダーが試したどの形式でも、そのバイト列を鍵として読み取れなかったという意味です。
発生する理由
リテラルの \n を含む環境変数から読み込んだ PEM
よくあるシークレットマネージャーや .env ファイルは、「-----BEGIN PRIVATE KEY-----\nMIG...」のように、改行をバックスラッシュと n の 2 文字のまま渡すことがよくあります。OpenSSL からは有効な PEM の区切りを持たない 1 行のファイルに見えるため、解析を諦めます。
空文字列、または鍵ではない内容
よくある変数の中身が ""、(ファイルの内容ではなく)ファイルパス、JSON の塊、あるいは生の鍵が必要な場面での証明書になっています。PEM/DER の鍵データ以外のものは、すべてまさにこのエラーになります。
API に対して鍵の種類が違う
よくある公開鍵の PEM を createPrivateKey() に渡すと、このメッセージで失敗します。デコーダーは秘密鍵の構造を探しますが、見つからないためです。逆はエラーになりません。createPublicKey() は秘密鍵を受け取り、そこから公開鍵を導出します。
形式の指定がない DER のバイト列
ときどき生の DER をただの Buffer として渡すと、デフォルトで PEM として解析されます。{ format: "der", type: "pkcs8" | "spki" | "sec1" } を指定しないと、デコーダーはどの構造を想定すればよいかわかりません。
修正方法
- 1.
環境変数から渡された PEM を正規化し、ラベルを確認する
改行を復元し、1 行目を出力してください。createPrivateKey を呼び出す箇所でラベルが PUBLIC KEY になっていれば、変数に別の鍵が割り当てられています。
js const pem = process.env.SIGNING_KEY.replace(/\\n/g, "\n"); console.log(pem.split("\n")[0]); // -----BEGIN PRIVATE KEY----- → createPrivateKey(pem) // -----BEGIN PUBLIC KEY----- → createPublicKey(pem) // -----BEGIN EC PRIVATE KEY----- → createPrivateKey(pem) (SEC1, also fine) - 2.
DER であることを明示する
鍵がバイナリの DER(データベースの BLOB、JWKS からの変換、protobuf など)であれば、format と type を明示してください。デコーダーは推測しません。
js import { createPrivateKey } from "node:crypto"; const key = createPrivateKey({ key: derBuffer, format: "der", type: "pkcs8", // or "sec1" for BEGIN EC PRIVATE KEY material }); - 3.
Node の外で鍵データを検証する
そのバイト列が実際に何なのかを OpenSSL で確認してください。これも失敗する場合はデータ自体が壊れているので、Node の呼び出しではなく、データの出どころを修正してください。
bash openssl pkey -in key.pem -noout -text | head # for DER: openssl pkey -in key.der -inform der -noout -text | head