SubtleCrypto: deriveBits() メソッド

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

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

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

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

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

構文

js
deriveBits(algorithm, baseKey, length)

引数

algorithm

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

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

関連情報