本文へスキップ
ecdsa.com
WebCrypto SubtleCrypto.importKeyWebCrypto

エラーメッセージ

TypeError: Failed to execute 'importKey' on 'SubtleCrypto': The provided value is not of type '(ArrayBuffer or ArrayBufferView or JsonWebKey)'.

別の表記

  • TypeError: SubtleCrypto.importKey: Argument 2 is not an object.
  • TypeError: Type error

上記は Chromium のテキストです。Firefox は「SubtleCrypto.importKey: Argument 2 is not an object.」、Safari/WebKit は単に「Type error」と表示します。Node.js は同じ呼び出しに対して `ERR_INVALID_ARG_TYPE` を報告します。

WebCrypto SubtleCrypto.importKey — PEM text passed as keyData (Chromium / Firefox / WebKit)

このエラーの意味

`importKey` が `keyData` として文字列を受け取りました。WebCrypto はテキストを一切解析しません。`"spki"`、`"pkcs8"`、`"raw"` ではバイナリの DER(`ArrayBuffer` または型付き配列)を、`"jwk"` では JavaScript のオブジェクトを要求します。ブラウザーは形式や鍵を調べる前、引数の変換の段階で呼び出しを拒否します。そのため、PEM 自体はまったく問題ない場合もあります。

発生する理由

修正方法

  1. 1.

    アーマーを取り除いてバイト列にデコードする

    BEGIN/END 行と空白を取り除いて base64 デコードし、ラベルで形式を選んでください。`PUBLIC KEY` → `spki`、`PRIVATE KEY` → `pkcs8` です。

    js
    function pemToDer(pem) {
      const base64 = pem.replace(/-----(BEGIN|END) [A-Z ]+-----/g, "").replace(/\s+/g, "");
      return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
    }
    
    const publicKey = await crypto.subtle.importKey(
      "spki", pemToDer(publicKeyPem),               // "PUBLIC KEY" -> spki, "PRIVATE KEY" -> pkcs8
      { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"],
    );
  2. 2.

    JWK はオブジェクトとして渡す

    JWKS エンドポイントは最初からオブジェクトを返します。JSON テキストは一度だけ解析し、一致する曲線を指定してそのオブジェクトを渡してください。

    js
    const jwk = JSON.parse(jwkText);                  // an object, not the JSON string
    const key = await crypto.subtle.importKey("jwk", jwk, { name: "ECDSA", namedCurve: jwk.crv }, false, ["verify"]);

関連するエラー

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