作为一个全能编程开发工程师,我们需要掌握各种加密算法和随机数生成方法。而window.crypto作为前端浏览器的内置加密库,为我们提供了一系列的加密和随机数生成功能。在本文中,我们将从多个方面对window.crypto进行详细的阐述。
一、window.crypto.subtle
Window.crypto.subtle 是一个只读的窗口属性,它可以进行高级加密标准(AES)、密码决定函数(PBKDF2、HKDF)、消息认证代码(HMAC)、RSA 签名、ECDSA 签名和验证等一系列加密操作。与传统的Crypto对象相比,Window.crypto.subtle返回的是Promise对象,而非直接返回加密结果,更符合现代异步编程思想。
下面,我们来看一个生成对称密钥的例子:
window.crypto.subtle.generateKey(
{
name: "AES-CBC",
length: 256, // 可选的长度
},
true, // 是否可导出
["encrypt", "decrypt"] // 期望的用途
)
.then(function(key){
console.log(key);
})
.catch(function(err){
console.error(err);
});
在这个例子中,我们使用了generateKey方法通过AES-CBC算法生成一组对称密钥。其中,length是可选参数,如果不传则会生成默认长度的密钥。接下来,我们可以在key对象中看到密钥的详细信息:
CryptoKey {
algorithm: {name: "AES-CBC", length: 256},
type: "secret",
extractable: true,
usages: ["encrypt", "decrypt"],
}
通过这个例子,我们不仅学会了使用generateKey方法生成对称密钥,还学会了如何使用Promise对象处理异步操作,更加熟悉了Web API的设计。
二、window.crypto.subtle 用途
除了生成密钥外,window.crypto.subtle还支持一些常用的加密操作,如加密、解密、签名和验证等。
下面,我们以AES算法为例,演示如何使用window.crypto.subtle进行加密和解密操作:
async function encryptText(text, key) {
const encoder = new TextEncoder();
const data = encoder.encode(text);
const iv = window.crypto.getRandomValues(new Uint8Array(16));
const algorithm = { name: 'AES-CBC', iv };
const encryptedData = await window.crypto.subtle.encrypt(algorithm, key, data);
const array = Array.from(new Uint8Array(iv.buffer), byte => byte.toString(16));
return {
iv: array.join(''),
data: btoa(String.fromCharCode(...new Uint8Array(encryptedData))),
};
}
async function decryptText(text, iv, key) {
const decoder = new TextDecoder();
const encryptedData = Uint8Array.from(atob(text), c => c.charCodeAt(0));
const algorithm = { name: 'AES-CBC', iv: Uint8Array.from(iv, c => parseInt(c, 16)) };
const decryptedData = await window.crypto.subtle.decrypt(algorithm, key, encryptedData);
return decoder.decode(decryptedData);
}
(async function() {
const key = await window.crypto.subtle.generateKey(
{ name: 'AES-CBC', length: 256 },
true,
['encrypt', 'decrypt'],
);
const encrypted = await encryptText('Hello, world!', key);
console.log(encrypted);
const decrypted = await decryptText(encrypted.data, encrypted.iv, key);
console.log(decrypted);
})();
在这个例子中,我们使用了TextEncoder 和 TextDecoder 对象将文本转换成二进制数据,使用Uint8Array和btoa方法将二进制数据转换成base64编码的字符串,并使用parseInt方法将十六进制的字符串转换成数值。这个例子还为我们展示了如何使用异步函数async/await,更加简洁和清晰地书写代码。
三、window.crypto.random
window.crypto.random对象提供了非加密的伪随机数生成方法。window.crypto 生成的伪随机数的安全强度是足够的,用于生成密码的盐值、创建随机数、防止CSRF攻击等等。
我们可以通过以下代码快速生成一个指定范围的随机整数:
function randomInt(min, max) {
const difference = max - min;
const array = new Uint32Array(1);
window.crypto.getRandomValues(array);
return Math.floor(array[0] / 4294967296 * difference) + min;
}
console.log(randomInt(0, 100));
在这个例子中,我们使用Uint32Array对象生成一个无符号32位整型数组,并通过Math.floor方法计算出随机整数。
四、window.crypto.getRandomValues
window.crypto.getRandomValues方法提供了生成加密强度随机数的方式。这些随机数由操作系统提供的由硬件生成器生成,强度足够高,并不会受到外界的影响。
我们来看一个随机生成16位长度的十六进制字符串的例子:
function randomHex(len) {
const array = new Uint8Array(len / 2);
window.crypto.getRandomValues(array);
return Array.from(array, (byte) => {
return ('0' + byte.toString(16)).slice(-2);
}).join('');
}
console.log(randomHex(16));
在这个例子中,我们使用Uint8Array对象生成一个无符号8位整型数组,并使用Array.from和slice方法将随机数转换成十六进制数。
总结
在本文中,我们通过四个小节全方位地介绍了window.crypto库,包括Window.crypto.subtle、Window.crypto.subtle用途、Window.crypto.random和Window.crypto.getRandomValues等部分的使用方法。在日常的编程开发中,我们可以利用这些方法,使我们的数据更加安全,应对更多类型的加密需求。了解window.crypto,是成为一名全能编程开发工程师的必经之路。