SubtleCrypto.sign()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
SubtleCrypto
接口的 sign()
方法用于生成数字签名。
它以签名密钥、一些特定于算法的参数和待签名的数据作为参数,返回一个 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" }
形式的对象。
- 要使用 RSASSA-PKCS1-v1_5,请传递字符串
key
-
一个包含了用于签名的密钥的
CryptoKey
对象。 如果algorithm
标识了公开密钥加密算法,则它是一个私钥。 data
-
一个包含待签名数据的
ArrayBuffer
、TypedArray
或DataView
对象。
返回值
一个 Promise
,会兑现包含数据签名的
ArrayBuffer
对象。
异常
当遇到以下异常时,promise 将会被拒绝:
InvalidAccessError
DOMException
-
当签名密钥不是要求的签名算法的密钥,或尝试使用未知或不适用于签名的算法时触发。
支持的算法
Web Crypto API 提供了 4 种可用于签名和签名验证的算法。
其中的三种算法(RSASSA-PKCS1-v1_5、RSA-PSS 和 ECDSA)是公开密钥加密算法,它们使用私钥进行签名,使用公钥验证签名。所有的算法均使用摘要算法在签名前将消息计算为短的、固定大小的散列值。除了 ECDSA(是将摘要算法传递给 algorithm
对象),其他算法均是通过将参数传递给 generateKey()
或 importKey()
函数来选择摘要算法的。
第四种算法(HMAC)使用相同的算法、密钥来签名和验证签名:这意味着签名验证的密钥必须保密,换句话说,该算法不适用与很多签名的场景。但是,当签名者和验证签名者是同一个实体时,这也是一个不错的选择。
RSASSA-PKCS1-v1_5
RSASSA-PKCS1-v1_5 算法在 RFC 3447 中定义。
RSA-PSS
ECDSA
HMAC
HMAC 算法根据 FIPS 198-1 标准 计算和验证基于散列的消息认证码。
需要在传入 generateKey()
的 HmacKeyGenParams
对象或传入 importKey()
的 HmacImportParams
对象中指定要使用的散列算法。
示例
备注:你可以在 Github 上尝试可用的示例。
RSASSA-PKCS1-v1_5
以下代码从文本框获取内容,将其编码,并使用私钥对其进行签名。在 GitHub 上查看完整代码。
/*
从“message”文本框获取内容,并将其编码为
我们可用于签名运算的形式。
*/
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 上查看完整代码。
/*
从“message”文本框获取内容,并将其编码为
我们可用于签名运算的形式。
*/
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 上查看完整代码。
/*
从“message”文本框获取内容,并将其编码为
我们可用于签名运算的形式。
*/
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 上查看完整代码。
/*
从“message”文本框获取内容,并将其编码为
我们可用于签名运算的形式。
*/
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);
规范
Specification |
---|
Web Cryptography API # SubtleCrypto-method-sign |
浏览器兼容性
BCD tables only load in the browser
参见
SubtleCrypto.verify()
- RFC 3447 定义了 RSASSA-PKCS1-v1_5。
- RFC 3447 定义了 RSA-PSS。
- FIPS-186 定义了 ECDSA。
- FIPS 198-1 定义了 HMAC。