Spec-Zone.ru › Web APIs

SubtleCrypto: метод sign()

Базовая Широко поддерживается *

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

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

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

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

Примечание: Эта функция доступна в Веб-воркерах.

Метод sign() интерфейса SubtleCrypto генерирует цифровую подпись.

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

Вы можете использовать соответствующий метод SubtleCrypto.verify() для проверки подписи.

Синтаксис

sign(algorithm, key, data)

Параметры

algorithm

Строка или объект, который определяет используемый алгоритм подписи и его параметры:

  • Для использования RSASSA-PKCS1-v1_5, передайте строку RSASSA-PKCS1-v1_5 или объект в формате { name: "RSASSA-PKCS1-v1_5" }.
  • Для использования RSA-PSS, передайте объект RsaPssParams.
  • Для использования ECDSA, передайте объект EcdsaParams.
  • Для использования HMAC, передайте строку HMAC или объект в формате { name: "HMAC" }.
  • Для использования Ed25519, передайте строку Ed25519 или объект в формате { name: "Ed25519" }.
key

Объект CryptoKey, содержащий ключ, используемый для подписи. Если algorithm идентифицирует криптосистему с открытым ключом, это закрытый ключ.

data

Объект ArrayBuffer, TypedArray или DataView, содержащий данные для подписи.

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

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

Исключения

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

InvalidAccessError DOMException

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

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

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

RSASSA-PKCS1-v1_5, RSA-PSS, ECDSA и Ed25519 являются криптосистемами с открытым ключом, которые используют закрытый ключ для подписи и открытый ключ для проверки. Все эти системы используют алгоритм хеширования digest algorithm для хеширования сообщения до короткого фиксированного размера перед подписью.

  • Для RSASSA-PKCS1-v1_5 и RSA-PSS выбор алгоритма хеширования передаётся в функции generateKey() или importKey().
  • Для ECDSA выбор алгоритма хеширования включён в параметр algorithm , переданный в функцию sign().
  • Для Ed25519 алгоритм хеширования всегда SHA-512.

Алгоритм HMAC отличается от других тем, что он не является криптосистемой с открытым ключом: он использует один и тот же алгоритм и ключ для подписи и проверки. Это означает, что ключ проверки должен храниться в секрете, что, в свою очередь, означает, что этот алгоритм не подходит для многих случаев использования подписи. Однако это может быть хорошим выбором, когда подписывающий и проверяющий являются одним и тем же субъектом.

RSASSA-PKCS1-v1_5

Алгоритм RSASSA-PKCS1-v1_5 описан в RFC 3447.

RSA-PSS

Алгоритм RSA-PSS описан в RFC 3447.

Он отличается от RSASSA-PKCS1-v1_5 тем, что включает случайную соль в операцию подписи, поэтому одинаковое сообщение, подписанное одним и тем же ключом, не приведет к одной и той же подписи каждый раз. Дополнительное свойство, определяющее длину соли, передается в функции sign() и verify() при их вызове.

ECDSA

ECDSA (Эллиптический криптографический алгоритм цифровой подписи) — это вариант алгоритма цифровой подписи, описанного в FIPS-186, который использует криптографию эллиптических кривых (RFC 6090).

Подписи кодируются как значения s1 и s2 , указанные в RFC 6090 (известные соответственно как r и s в RFC 4754), каждое в массиве байтов в порядке big-endian, с длиной, равной размеру кривой в битах, округлённой до целого числа байтов. Эти значения конкатенируются в этом порядке.

Это кодирование также было предложено стандартом IEEE 1363-2000, и иногда называется форматом IEEE P1363. Оно отличается от структуры подписи X.509, которая является форматом по умолчанию, создаваемым некоторыми инструментами и библиотеками, такими как OpenSSL.

Ed25519

Ed25519 — алгоритм цифровой подписи, построенный на кривой Curve25519, который является частью семейства алгоритмов EdDSA (Edwards-Curve Digital Signature Algorithm), определённых в RFC 8032.

HMAC

Алгоритм HMAC вычисляет и проверяет коды аутентификации сообщений на основе хешей в соответствии со стандартом FIPS 198-1 (PDF).

Используемый алгоритм хеширования задаётся в объекте HmacKeyGenParams, передаваемом в generateKey(), или в объекте HmacImportParams, передаваемом в importKey().

Алгоритм HMAC использует один и тот же алгоритм и ключ для подписи и проверки: это означает, что ключ проверки должен храниться в секрете, что, в свою очередь, означает, что этот алгоритм не подходит для многих случаев использования подписи. Однако это может быть хорошим выбором, когда подписывающий и проверяющий являются одним и тем же субъектом.

Примеры

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

RSASSA-PKCS1-v1_5

Этот код извлекает содержимое текстового поля, кодирует его для подписи и подписывает его с помощью закрытого ключа. Посмотрите полный исходный код на GitHub.

/*
Fetch the contents of the "message" textbox, and encode it
in a form we can use for the sign operation.
*/
function getMessageEncoding() {
  const messageBox = document.querySelector(".rsassa-pkcs1 #message");
  let message = messageBox.value;
  let enc = new TextEncoder();
  return enc.encode(message);
}

let encoded = getMessageEncoding();
let signature = await window.crypto.subtle.sign(
  "RSASSA-PKCS1-v1_5",
  privateKey,
  encoded,
);

RSA-PSS

Этот код извлекает содержимое текстового поля, кодирует его для подписи и подписывает его с помощью закрытого ключа. Посмотрите полный исходный код на GitHub.

/*
Fetch the contents of the "message" textbox, and encode it
in a form we can use for the sign operation.
*/
function getMessageEncoding() {
  const messageBox = document.querySelector(".rsa-pss #message");
  let message = messageBox.value;
  let enc = new TextEncoder();
  return enc.encode(message);
}

let encoded = getMessageEncoding();
let signature = await window.crypto.subtle.sign(
  {
    name: "RSA-PSS",
    saltLength: 32,
  },
  privateKey,
  encoded,
);

ECDSA

Этот код извлекает содержимое текстового поля, кодирует его для подписи и подписывает его с помощью закрытого ключа. Посмотрите полный исходный код на GitHub.

/*
Fetch the contents of the "message" textbox, and encode it
in a form we can use for the sign operation.
*/
function getMessageEncoding() {
  const messageBox = document.querySelector(".ecdsa #message");
  let message = messageBox.value;
  let enc = new TextEncoder();
  return enc.encode(message);
}

let encoded = getMessageEncoding();
let signature = await window.crypto.subtle.sign(
  {
    name: "ECDSA",
    hash: { name: "SHA-384" },
  },
  privateKey,
  encoded,
);

HMAC

Этот код извлекает содержимое текстового поля, кодирует его для подписи и подписывает его с помощью секретного ключа. Посмотрите полный исходный код на GitHub.

/*
Fetch the contents of the "message" textbox, and encode it
in a form we can use for the sign operation.
*/
function getMessageEncoding() {
  const messageBox = document.querySelector(".hmac #message");
  let message = messageBox.value;
  let enc = new TextEncoder();
  return enc.encode(message);
}

let encoded = getMessageEncoding();
let signature = await window.crypto.subtle.sign("HMAC", key, encoded);

Ed25519 (генерация ключа, подпись и проверка)

Этот код генерирует пару ключей Ed25519, использует закрытый ключ для подписания (кодированного) содержимого текстового поля <input>, а затем проверяет подпись с помощью открытого ключа. Он основан на этом исходном коде на GitHub, который вы можете запустить онлайн здесь.

HTML

HTML определяет элемент <input> содержащий текст, подлежащий подписанию, и кнопку, которая запускает операцию по созданию ключей, подписанию текста и проверке подписи.

<label for="message">Enter a message to sign:</label>
<input
  type="text"
  id="message"
  name="message"
  size="25"
  value="The lion roars near dawn" />

<input id="sign-button" type="button" value="Run" />

JavaScript

JavaScript сначала получает элементы #sign-button и #message <input>, затем добавляет обработчик события click на кнопку. Обработчик событий очищает лог и выполняет другие операции, передавая содержимое элемента <input>.

const button = document.querySelector("#sign-button");
const input = document.querySelector("#message");

button.addEventListener("click", () => {
  // Clear log
  logElement.innerText = "";
  logElement.scrollTop = logElement.scrollHeight;
  // Run test
  test(input.value);
});

Сначала он генерирует ключи с помощью алгоритма Ed25519, затем кодирует текст и подписывает этот текст с использованием закрытого ключа. Наконец, он вызывает SubtleCrypto.verify() с открытым ключом для проверки подписи.

async function test(data) {
  log(`Message: ${data}`);
  try {
    // Generate keys
    const { publicKey, privateKey } = await crypto.subtle.generateKey(
      {
        name: "Ed25519",
      },
      true,
      ["sign", "verify"],
    );

    log(`publicKey: ${publicKey}, type: ${publicKey.type}`);
    log(`privateKey: ${privateKey},  type: ${privateKey.type}`);

    // Encode data prior to signing
    const encoder = new TextEncoder();
    encodedData = encoder.encode(data);

    // Log the first part of the encoded data
    const shorterEncodedBuffer = new Uint8Array(encodedData.buffer, 0, 14);
    log(
      `encodedData: ${shorterEncodedBuffer}...[${encodedData.byteLength} bytes total]`,
    );
    //log(`encodedData: ${encodedData}`);

    // Sign the data using the private key.
    const signature = await crypto.subtle.sign(
      {
        name: "Ed25519",
      },
      privateKey,
      encodedData,
    );

    // Log the first part of the signature data
    const signatureBuffer = new Uint8Array(signature, 0, 14);
    log(
      `signature: ${signatureBuffer}...[${signature.byteLength} bytes total]`,
    );

    // Verify the signature using the public key
    const verifyResult = await crypto.subtle.verify(
      {
        name: "Ed25519",
      },
      publicKey,
      signature,
      encodedData,
    );

    // Log result - true if the text was signed with the corresponding public key.
    log(`signature verified?: ${verifyResult}`);
  } catch (error) {
    log(error);
  }
}

Результат

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

Спецификация
Web Cryptography API
# SubtleCrypto-method-sign

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

Рабочий стол Мобильный
Chrome Edge Firefox Opera Safari Chrome Android Firefox для Android Opera Android Safari на iOS Samsung Internet WebView Android
sign 37 79
12–79Не поддерживается: RSA-PSS, ECDSA.
34 24 7 37 34 24 7 3.0 37
ed25519 113 113 129 99
17Генерирует случайные подписи в соответствии со спецификацией draft-irtf-cfrg-det-sigs-with-noise, а не детерминированные подписи в соответствии со спецификацией RFC 8032.
113 129 Нет
17Генерирует случайные подписи в соответствии со спецификацией draft-irtf-cfrg-det-sigs-with-noise, а не детерминированные подписи в соответствии со спецификацией RFC 8032.
Нет Нет

См. также

  • SubtleCrypto.verify().
  • RFC 3447 описывает RSASSA-PKCS1-v1_5.
  • RFC 3447 описывает RSA-PSS.
  • FIPS-186 описывает ECDSA.
  • FIPS 198-1 описывает HMAC.

© 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/sign

Spec-Zone.ru

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