使用SubtleCrypto.generateKey()方法可以生成随机CryptoKey,这个方法返回一个期约,
解决为一个或多个CryptoKey 实例。使用时需要给这个方法传入一个指定目标算法的参数对象、一个
表示密钥是否可以从CryptoKey 对象中提取出来的布尔值,以及一个表示这个密钥可以与哪个
SubtleCrypto 方法一起使用的字符串数组(keyUsages)。
由于不同的密码系统需要不同的输入来生成密钥,上述参数对象为每种密码系统都规定了必需的
输入:
RSA 密码系统使用RsaHashedKeyGenParams 对象;
ECC 密码系统使用EcKeyGenParams 对象;
HMAC 密码系统使用HmacKeyGenParams 对象;
AES 密码系统使用AesKeyGenParams 对象。
keyUsages 对象用于说明密钥可以与哪个算法一起使用。至少要包含下列中的一个字符串:
encrypt
decrypt
sign
verify
deriveKey
deriveBits
wrapKey
unwrapKey
假设要生成一个满足如下条件的对称密钥:
支持AES-CTR 算法;
密钥长度128 位;
不能从CryptoKey 对象中提取;
可以跟encrypt()和decrypt()方法一起使用。
那么可以参考如下代码:
(async function() {
const params = {
name: ‘AES-CTR’,
length: 128
};
const keyUsages = [‘encrypt’, ‘decrypt’];
const key = await crypto.subtle.generateKey(params, false, keyUsages);
console.log(key);
// CryptoKey {type: “secret”, extractable: true, algorithm: {…}, usages: Array(2)}
})();
假设要生成一个满足如下条件的非对称密钥:
支持ECDSA 算法;
使用P-256 椭圆曲线;
可以从CryptoKey 中提取;
可以跟sign()和verify()方法一起使用。
那么可以参考如下代码:
(async function() {
const params = {
name: ‘ECDSA’,
namedCurve: ‘P-256’
};
const keyUsages = [‘sign’, ‘verify’];
const {publicKey,privateKey} = await crypto.subtle.generateKey(params, true,
keyUsages);
console.log(publicKey);
// CryptoKey {type: “public”, extractable: true, algorithm: {…}, usages: Array(1)}
console.log(privateKey);
// CryptoKey {type: “private”, extractable: true, algorithm: {…}, usages: Array(1)}
})();导出和导入密钥
如果密钥是可提取的,那么就可以在CryptoKey 对象内部暴露密钥原始的二进制内容。使用
exportKey()方法并指定目标格式(“raw”、“pkcs8”、“spki"或"jwk”)就可以取得密钥。这个方
法返回一个期约,解决后的ArrayBuffer 中包含密钥:
(async function() {
const params = {
name: ‘AES-CTR’,
length: 128
};
const keyUsages = [‘encrypt’, ‘decrypt’];
const key = await crypto.subtle.generateKey(params, true, keyUsages);
const rawKey = await crypto.subtle.exportKey(‘raw’, key);
console.log(new Uint8Array(rawKey));
// Uint8Array[93, 122, 66, 135, 144, 182, 119, 196, 234, 73, 84, 7, 139, 43, 238,
// 110]
})();
与exportKey()相反的操作要使用importKey()方法实现。importKey()方法的签名实际上是
generateKey()和exportKey()的组合。下面的方法会生成密钥、导出密钥,然后再导入密钥:
(async function() {
const params = {
name: ‘AES-CTR’,
length: 128
};
const keyUsages = [‘encrypt’, ‘decrypt’];
const keyFormat = ‘raw’;
const isExtractable = true;
const key = await crypto.subtle.generateKey(params, isExtractable, keyUsages);
const rawKey = await crypto.subtle.exportKey(keyFormat, key);
const importedKey = await
crypto.subtle.importKey(keyFormat, rawKey, params.name,
isExtractable, keyUsages);
console.log(importedKey);
// CryptoKey {type: “secret”, extractable: true, algorithm: {…}, usages: Array(2)}
})();