Метод subtle.generateKey

Метод crypto.subtle.generateKey() предназначен для генерации криптографических ключей в рамках Web Crypto API. Он используется для создания как симметричных, так и асимметричных ключей, которые впоследствии применяются для шифрования, дешифрования, подписания данных и проверки подписей.

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


Сигнатура метода

crypto.subtle.generateKey(algorithm, extractable, keyUsages)

Параметры:

  • algorithm — объект или строка, определяющая алгоритм генерации ключа
  • extractable — логическое значение, указывающее, можно ли экспортировать ключ
  • keyUsages — массив строк, определяющий допустимые операции с ключом

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

  • Для симметричных алгоритмов — объект CryptoKey

  • Для асимметричных алгоритмов — объект CryptoKeyPair:

    {
      publicKey: CryptoKey,
      privateKey: CryptoKey
    }

Основные алгоритмы

Симметричные алгоритмы

  • AES-CBC
  • AES-GCM
  • AES-CTR
  • HMAC

Асимметричные алгоритмы

  • RSA-OAEP
  • RSA-PSS
  • RSASSA-PKCS1-v1_5
  • ECDSA
  • ECDH

Генерация симметричного ключа (AES)

const key = await crypto.subtle.generateKey(
  {
    name: "AES-GCM",
    length: 256
  },
  true,
  ["encrypt", "decrypt"]
);

Пояснения:

  • length: длина ключа в битах (128, 192 или 256)
  • extractable: true позволяет экспортировать ключ
  • keyUsages: операции шифрования и дешифрования

Генерация ключа для HMAC

const key = await crypto.subtle.generateKey(
  {
    name: "HMAC",
    hash: "SHA-256",
    length: 256
  },
  true,
  ["sign", "verify"]
);

Особенности:

  • hash: используемый хэш-алгоритм
  • ключ используется для подписи и проверки

Генерация пары ключей RSA

const keyPair = await crypto.subtle.generateKey(
  {
    name: "RSA-OAEP",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA-256"
  },
  true,
  ["encrypt", "decrypt"]
);

Параметры:

  • modulusLength: длина модуля (2048 или 4096)
  • publicExponent: обычно [1, 0, 1] (65537)
  • hash: алгоритм хэширования

Генерация ключей для подписи (RSA-PSS)

const keyPair = await crypto.subtle.generateKey(
  {
    name: "RSA-PSS",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA-256"
  },
  true,
  ["sign", "verify"]
);

Генерация ключей на эллиптических кривых (ECDSA)

const keyPair = await crypto.subtle.generateKey(
  {
    name: "ECDSA",
    namedCurve: "P-256"
  },
  true,
  ["sign", "verify"]
);

Поддерживаемые кривые:

  • P-256
  • P-384
  • P-521

Генерация ключей для обмена (ECDH)

const keyPair = await crypto.subtle.generateKey(
  {
    name: "ECDH",
    namedCurve: "P-256"
  },
  false,
  ["deriveKey", "deriveBits"]
);

Особенности:

  • extractable: false — приватный ключ не может быть экспортирован
  • используется для генерации общего секрета

Параметр extractable

Определяет, можно ли извлечь ключ из CryptoKey в виде сырого материала.

  • true — ключ можно экспортировать (например, через exportKey)
  • false — ключ остается внутри криптографического контекста

Важно: закрытые ключи часто делают неэкспортируемыми для повышения безопасности.


Параметр keyUsages

Определяет, какие операции разрешены для ключа:

Значение Назначение
encrypt Шифрование
decrypt Дешифрование
sign Подпись
verify Проверка подписи
deriveKey Генерация ключа
deriveBits Генерация битов
wrapKey Оборачивание ключа
unwrapKey Разворачивание ключа

Несоответствие между алгоритмом и keyUsages приводит к ошибке.


Обработка ошибок

Метод может выбрасывать исключения:

  • SyntaxError — неверные параметры
  • NotSupportedError — алгоритм не поддерживается
  • InvalidAccessError — некорректные keyUsages

Пример обработки:

try {
  const key = await crypto.subtle.generateKey(...);
} catch (error) {
  console.error(error);
}

Безопасностные аспекты

  • Генерация ключей происходит внутри защищённого контекста браузера
  • Приватные ключи не должны быть экспортируемыми без необходимости
  • Использование современных алгоритмов (например, AES-GCM, SHA-256) предпочтительно
  • RSA с длиной ключа менее 2048 бит считается небезопасным

Практические сценарии использования

Шифрование данных:

  • Генерация AES-ключа для локального хранения данных

Аутентификация:

  • Использование HMAC для подписи запросов

Обмен ключами:

  • ECDH для установки защищённого канала

Цифровая подпись:

  • ECDSA или RSA-PSS для проверки подлинности данных

Взаимодействие с другими методами

Сгенерированные ключи используются в:

  • crypto.subtle.encrypt()
  • crypto.subtle.decrypt()
  • crypto.subtle.sign()
  • crypto.subtle.verify()
  • crypto.subtle.deriveKey()
  • crypto.subtle.exportKey()

Особенности реализации

  • Работает только в безопасном контексте (HTTPS)
  • Поддержка зависит от браузера
  • В Node.js доступен через crypto.webcrypto.subtle

Типичные ошибки

1. Неправильные keyUsages:

["encrypt"] // для RSA-PSS — ошибка

2. Неверный алгоритм:

{ name: "AES", length: 256 } // должно быть AES-GCM, AES-CBC и т.д.

3. Попытка экспортировать неэкспортируемый ключ:

extractable: false

Проверка результата

console.log(key instanceof CryptoKey); // true

Для пары ключей:

console.log(keyPair.publicKey);
console.log(keyPair.privateKey);

Производительность

  • Генерация асимметричных ключей (RSA) — ресурсоёмкая операция
  • Эллиптические кривые (ECDSA, ECDH) быстрее и компактнее
  • Симметричные ключи генерируются практически мгновенно

Итоговая структура использования

  1. Выбор алгоритма
  2. Определение параметров
  3. Указание допустимых операций
  4. Генерация ключа
  5. Использование в криптографических операциях