Перейти к содержимому
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"]);

Связанные ошибки

Открыть всю базу ошибок подписей