在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
由於並不常用,在這裏不記錄具體用法,有空再詳細說明。