SubtleCrypto: deriveBits() メソッド

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

安全なコンテキスト用: この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

deriveBits()SubtleCrypto インターフェイスのメソッドで、ベース鍵からビットの配列を導出するために使用することができます。

引数として、ベース鍵、使用する導出アルゴリズム、導出するビットの長さを用います。これは派生ビットを格納した ArrayBuffer で履行される Promise を返します。

このメソッドは SubtleCrypto.deriveKey() ととても似ていますが、 deriveKey()ArrayBuffer ではなく CryptoKey オブジェクトを返す点が異なります。基本的に deriveKey()deriveBits() に続く importKey() から構成されます。

この関数は deriveKey() と同じ導出アルゴリズム、ECDH、HKDF、PBKDF2 に対応しています。これらのアルゴリズムの詳細については、対応しているアルゴリズムを参照してください。

構文

js
deriveBits(algorithm, baseKey, length)

引数

algorithm

使用する導出アルゴリズムを定義するオブジェクトです。

  • ECDH を使用するには、 EcdhKeyDeriveParams オブジェクトを渡してください。
  • HKDF を使用するには、 HkdfParams オブジェクトを渡してください。
  • PBKDF2 を使用するには、 Pbkdf2Params オブジェクトを渡してください。
baseKey

導出アルゴリズムへの入力を表す CryptoKey です。 algorithm が ECDH の場合、これは ECDH 秘密鍵となります。例えば、 PBKDF2 の場合、 SubtleCrypto.importKey() を使用して CryptoKey としてインポートしたパスワードになります。

length

導出するビット数を表す数値。すべてのブラウザーに対応するためには、 8 の倍数である必要があります。

返値

導出されたビットを格納する ArrayBuffer で履行される Promise です。

例外

以下の例外が発生した場合、プロミスは拒否されます。

OperationError DOMException

deriveBits() 呼び出しの length 引数が NULL の場合、または length 引数が 8 の倍数でない一部の場合に発生します。

InvalidAccessError DOMException

ベース鍵がリクエストされた導出アルゴリズムの鍵でない場合、またはその鍵の CryptoKey.usages の値に deriveBits が格納されていない場合に発生します。

NotSupported DOMException

ベース鍵がリクエストされた導出アルゴリズムの鍵でない場合、またはその鍵の CryptoKey.usages の値に deriveBits が格納されていない場合に発生します。

対応しているアルゴリズム

メモ: GitHub 上の動作例を試してみてください

ECDH

この例では、 Alice と Bob がそれぞれ ECDH 鍵ペアを生成します。

次に、アリスの秘密鍵とボブの公開鍵を使用して共有秘密を導出します。動作例を試してみてください

js
async function deriveSharedSecret(privateKey, publicKey) {
  const sharedSecret = await window.crypto.subtle.deriveBits(
    {
      name: "ECDH",
      namedCurve: "P-384",
      public: publicKey,
    },
    privateKey,
    128,
  );

  const buffer = new Uint8Array(sharedSecret, 0, 5);
  const sharedSecretValue = document.querySelector(".ecdh .derived-bits-value");
  sharedSecretValue.classList.add("fade-in");
  sharedSecretValue.addEventListener("animationend", () => {
    sharedSecretValue.classList.remove("fade-in");
  });
  sharedSecretValue.textContent = `${buffer}…[${sharedSecret.byteLength} bytes total]`;
}

// Generate 2 ECDH key pairs: one for Alice and one for Bob
// In more normal usage, they would generate their key pairs
// separately and exchange public keys securely
const generateAlicesKeyPair = window.crypto.subtle.generateKey(
  {
    name: "ECDH",
    namedCurve: "P-384",
  },
  false,
  ["deriveBits"],
);

const generateBobsKeyPair = window.crypto.subtle.generateKey(
  {
    name: "ECDH",
    namedCurve: "P-384",
  },
  false,
  ["deriveBits"],
);

Promise.all([generateAlicesKeyPair, generateBobsKeyPair]).then((values) => {
  const alicesKeyPair = values[0];
  const bobsKeyPair = values[1];

  const deriveBitsButton = document.querySelector(".ecdh .derive-bits-button");
  deriveBitsButton.addEventListener("click", () => {
    // Alice then generates a secret using her private key and Bob's public key.
    // Bob could generate the same secret using his private key and Alice's public key.
    deriveSharedSecret(alicesKeyPair.privateKey, bobsKeyPair.publicKey);
  });
});

PBKDF2

この例では、ユーザーにパスワードを要求し、それを使用してPBKDF2を使用してビットを導出します。動作例を試してみてください

js
let salt;

/*
Get some key material to use as input to the deriveBits method.
The key material is a password supplied by the user.
*/
function getKeyMaterial() {
  const password = window.prompt("Enter your password");
  const enc = new TextEncoder();
  return window.crypto.subtle.importKey(
    "raw",
    enc.encode(password),
    { name: "PBKDF2" },
    false,
    ["deriveBits", "deriveKey"],
  );
}

/*
Derive some bits from a password supplied by the user.
*/
async function getDerivedBits() {
  const keyMaterial = await getKeyMaterial();
  salt = window.crypto.getRandomValues(new Uint8Array(16));
  const derivedBits = await window.crypto.subtle.deriveBits(
    {
      name: "PBKDF2",
      salt,
      iterations: 100000,
      hash: "SHA-256",
    },
    keyMaterial,
    256,
  );

  const buffer = new Uint8Array(derivedBits, 0, 5);
  const derivedBitsValue = document.querySelector(
    ".pbkdf2 .derived-bits-value",
  );
  derivedBitsValue.classList.add("fade-in");
  derivedBitsValue.addEventListener("animationend", () => {
    derivedBitsValue.classList.remove("fade-in");
  });
  derivedBitsValue.textContent = `${buffer}…[${derivedBits.byteLength} bytes total]`;
}

const deriveBitsButton = document.querySelector(".pbkdf2 .derive-bits-button");
deriveBitsButton.addEventListener("click", () => {
  getDerivedBits();
});

仕様書

Specification
Web Cryptography API
# SubtleCrypto-method-deriveBits

ブラウザーの互換性

BCD tables only load in the browser

関連情報