Spec-Zone.ru › Web APIs

SubtleCrypto: метод deriveBits()

Базовая реализация Широко доступна *

Эта функция хорошо отработана и работает на многих устройствах и версиях браузеров. Она доступна в браузерах с июля 2015 года.

* Некоторые части этой функции могут иметь разный уровень поддержки.

  • Подробнее
  • Полная совместимость
  • Отправить отзыв

Безопасный контекст: Эта функция доступна только в безопасных контекстах (HTTPS), в некоторых или во всех поддерживающих браузерах.

Примечание: Эта функция доступна в Web Workers.

Метод deriveBits() интерфейса SubtleCrypto может использоваться для получения массива битов из базового ключа.

Он принимает в качестве аргументов базовый ключ, алгоритм вывода и длину выводимых битов. Он возвращает Promise, который будет выполнен с ArrayBuffer, содержащим выведенные биты.

Этот метод очень похож на SubtleCrypto.deriveKey(), за исключением того, что deriveKey() возвращает объект CryptoKey, а не ArrayBuffer. По сути, deriveKey() состоит из deriveBits() и importKey().

Эта функция поддерживает те же алгоритмы вывода, что и deriveKey(): ECDH, HKDF, PBKDF2 и X25519. См. Поддерживаемые алгоритмы для более подробной информации об этих алгоритмах.

Синтаксис

deriveBits(algorithm, baseKey, length)

Параметры

algorithm

Объект, определяющий алгоритм вывода для использования.

  • Для использования ECDH передайте объект EcdhKeyDeriveParams, указав строку ECDH в качестве свойства name.
  • Для использования HKDF передайте объект HkdfParams.
  • Для использования PBKDF2 передайте объект Pbkdf2Params.
  • Для использования X25519 передайте объект EcdhKeyDeriveParams, указав строку X25519 в качестве свойства name.
baseKey

CryptoKey, представляющий входные данные для алгоритма вывода. Если algorithm — ECDH, это будет закрытый ключ ECDH. В противном случае это будет исходный материал ключа для функции вывода: например, для PBKDF2 это может быть пароль, импортированный как CryptoKey с помощью SubtleCrypto.importKey().

length

Число, представляющее количество выводимых битов. Для совместимости со всеми браузерами число должно быть кратно 8.

Возвращаемое значение

Promise, который выполняется с ArrayBuffer, содержащим выведенные биты.

Исключения

Обещание отклоняется, когда возникает одно из следующих исключений:

OperationError DOMException

Возникает, если параметр length вызова deriveBits() равен null, а также в некоторых случаях, если параметр length не кратен 8.

InvalidAccessError DOMException

Возникает, когда базовый ключ не является ключом для запрошенного алгоритма вывода или если значение CryptoKey.usages этого ключа не содержит deriveBits.

NotSupported DOMException

Возникает при попытке использовать алгоритм, который либо неизвестен, либо не подходит для вывода.

Поддерживаемые алгоритмы

См. раздел Поддерживаемые алгоритмы документации deriveKey().

Примеры

Примечание: Вы можете попробовать рабочие примеры на GitHub.

ECDH

В этом примере Алиса и Боб генерируют каждую пару ключей ECDH.

Затем мы используем закрытый ключ Алисы и открытый ключ Боба для вывода общего секрета. Полный код см. на GitHub.

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 generateAliceKeyPair = window.crypto.subtle.generateKey(
  {
    name: "ECDH",
    namedCurve: "P-384",
  },
  false,
  ["deriveBits"],
);

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

Promise.all([generateAliceKeyPair, generateBobKeyPair]).then((values) => {
  const aliceKeyPair = values[0];
  const bobKeyPair = 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(aliceKeyPair.privateKey, bobKeyPair.publicKey);
  });
});

X25519

В этом примере Алиса и Боб генерируют каждую пару ключей X25519. Затем мы используем закрытый ключ Алисы и открытый ключ Боба для вывода секрета и сравниваем его с секретом, выведенным с использованием закрытого ключа Боба и открытого ключа Алисы, чтобы показать, что они общие/тождественные.

HTML

HTML определяет две кнопки. Кнопка «Изменить ключи» нажимается для генерации новых пар ключей для Алисы и Боба. Кнопка «Вывести биты» нажимается для вывода общего секрета с текущим набором пар ключей.

<input id="buttonDeriveKeys" type="button" value="Derive bits" />
<input id="buttonChangeKeys" type="button" value="Change keys" />

JavaScript

Функция для генерации общего секрета с использованием алгоритма X25519 показана ниже. Она принимает закрытый ключ одной стороны и открытый ключ другой.

async function deriveSharedSecret(privateKey, publicKey) {
  return await window.crypto.subtle.deriveBits(
    {
      name: "X25519",
      public: publicKey,
    },
    privateKey,
    128,
  );
}

Код ниже добавляет функцию для генерации новых ключей для Алисы и Боба. Это делается в первый раз при загрузке JavaScript и повторяется всякий раз, когда нажимается кнопка «Изменить ключи» (это позволяет увидеть эффект изменения ключей на общем секрете).

let aliceKeyPair;
let bobKeyPair;

async function changeKeys() {
  try {
    aliceKeyPair = await window.crypto.subtle.generateKey(
      {
        name: "X25519",
      },
      false,
      ["deriveBits"],
    );

    bobKeyPair = await window.crypto.subtle.generateKey(
      {
        name: "X25519",
      },
      false,
      ["deriveBits"],
    );

    log("Keys changed");
  } catch (e) {
    log(e);
  }
}

changeKeys();

const changeKeysButton = document.querySelector("#buttonChangeKeys");

// Generate 2 X25519 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
changeKeysButton.addEventListener("click", changeKeys);

Код ниже добавляет функцию-обработчик, которая вызывается каждый раз при нажатии кнопки «Вывести биты». Обработчик генерирует общие секреты для Алисы и Боба с использованием метода deriveSharedSecret() , определённого выше, и регистрирует их для простоты сравнения.

const deriveBitsButton = document.querySelector("#buttonDeriveKeys");

deriveBitsButton.addEventListener("click", async () => {
  // Generate 2 X25519 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

  // 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.

  const sharedSecretAlice = await deriveSharedSecret(
    aliceKeyPair.privateKey,
    bobKeyPair.publicKey,
  );

  let buffer = new Uint8Array(sharedSecretAlice, 0, 10);
  log(`${buffer}…[${sharedSecretAlice.byteLength} bytes total] (Alice secret)`);

  const sharedSecretBob = await deriveSharedSecret(
    bobKeyPair.privateKey,
    aliceKeyPair.publicKey,
  );

  buffer = new Uint8Array(sharedSecretBob, 0, 10);
  log(`${buffer}…[${sharedSecretAlice.byteLength} bytes total] (Bob secret)`);
});

Результат

Нажмите кнопку «Вывести биты», чтобы сгенерировать и вывести общий секрет от Боба и ключей Алисы. Нажмите кнопку «Изменить ключи», чтобы изменить ключи X25519, используемые обеими сторонами.

PBKDF2

В этом примере мы запрашиваем у пользователя пароль, затем используем его для вывода некоторых битов с помощью PBKDF2. Полный код см. на GitHub.

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();
});

Спецификации

Спецификация
API криптографии веб-браузера
# SubtleCrypto-method-deriveBits

Совместимость с браузерами

Рабочие столы Мобильные устройства
Chrome Edge Firefox Opera Safari Chrome Android Firefox для Android Opera Android Safari в iOS Samsung Internet WebView Android
deriveBits 41 79
12–79["Не поддерживается: ECDH.", "Не поддерживаются: HKDF, PBKDF2."]
34 28 11 41 34 28 11 4.0 41
x25519 133 133 130 Нет 17 133 130 Нет 17 Нет 133

См. также

  • Спецификация HKDF.
  • Рекомендации NIST по производству ключей на основе паролей.
  • Сводка по хранению паролей.
  • Советы по выбору количества итераций для PBKDF2.

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveBits

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API