在JS中经常使用Math.Random|()函数来产生随机数,但这个函数产生的随机数并不具有真正的随机性,而且加密型不够强。因此在特定的需要加密性强的安全随机数时,可以使用JS提供的windows.crypto来生成随机数。
Window.crypto只读属性返回与全局对象关联的 Crypto对象。 这个对象允许网页访问某些加密相关服务。
为了确保足够的性能,不使用真正的随机数生成器,但是它们正在使用具有足够熵值伪随机数生成器。它所使用的 PRNG 的实现与其他不同,但适用于加密的用途。该实现还需要使用具有足够熵的种子。
使用crypto尽可能在https 环境下使用,否则有时会返回undefined 或者 空对象
函数比较
Math.random() : 返回介于 0(包含) ~ 1(不包含) 之间的一个随机数。该函数不是加密安全的随机数生成器。
window.crypto.getRandomValues(typedArray) : 返回非0的正整数,Crypto.getRandomValues(typedArray) 方法可以获取符合密码学安全性要求的随机值。
typedArray是一个基于整数的 TypedArray,其可以是 Int8Array、Uint8Array、Int16Array、 Uint16Array、 Int32Array 或 Uint32Array。生成的属技术会存储在typedArray 数组中。
使用方法
如果只需要生成安全随机数,可以按下面代码所示使用:
var arr = new Uint16Array(8);window.crypto.getRandomValues(arr);for (var i = 0; i < arr.length; i++) {console.log(arr[i]);}
这里需要注意:
window.crypto只能保证在通用浏览器上正常运行,如果要做兼容,需要使用如下前缀:
- webkit 兼容Chrome,Safari,Opera的新版本,几乎所有的iOS浏览器(包括iOS版的Firefox);基本上,任何基于WebKit的浏览器
- moz 兼容Firefox
- o 兼容旧版,WebKit之前的版本以及Opera版
- ms 兼容微软的Internet Explorer和Microsoft Edge
因此,要做全版本兼容,需要这样使用:
var arr = new Uint16Array(8);var crypto = window.crypto || window.webkitCrypto || window.mozCrypto || window.oCrypto || window.msCrypto;window.crypto.getRandomValues(arr);for (var i = 0; i < arr.length; i++) {console.log(arr[i]);}
除了生成安全随机数,window.crypto还可以对数据进行加解密(crypto rsa 只有一个算法(RSA-OAEP)支持加密 / 解密),通常用法有:
- 生成公私钥对:crypto.subtle.generateKey
- 导出公私钥: window.crypto.subtle.exportKe
- 导入公私钥:window.crypto.subtle.importKey
- 加密:window.crypto.subtle.wrapKey
- 解密:window.crypto.subtle.unwrapKey
- 签名:crypto.subtle.sign
- 验签:crypto.subtle.verify
- 加密明文:crypto.subtle.encrypt
- 解密密文:crypto.subtle.decrypt
由于并不常用,在这里不记录具体用法,有空再详细说明。