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" }.
- Для использования RSASSA-PKCS1-v1_5, передайте строку
key-
Объект
CryptoKey, содержащий ключ, используемый для подписи. Еслиalgorithmидентифицирует криптосистему с открытым ключом, это закрытый ключ. data-
Объект
ArrayBuffer,TypedArrayилиDataView, содержащий данные для подписи.
Возвращаемое значение
Promise, который выполняется с ArrayBuffer, содержащим подпись.
Исключения
Обещание отклоняется, когда возникает следующее исключение:
-
InvalidAccessErrorDOMException -
Возникает, когда ключ подписи не является ключом для запрошенного алгоритма подписи или при попытке использования неизвестного или непригодного для подписи алгоритма.
Поддерживаемые алгоритмы
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 | 7912–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