如果似乎使用window.crypto为 RNG 播种,如果不可用,则使用window.msCrypto并最终回退到当前时间。相关代码为:
var rng_state;
var rng_pool;
var rng_pptr;
// Mix in a 32-bit integer into the pool
function rng_seed_int(x) {
rng_pool[rng_pptr++] ^= x & 255;
rng_pool[rng_pptr++] ^= (x >> 8) & 255;
rng_pool[rng_pptr++] ^= (x >> 16) & 255;
rng_pool[rng_pptr++] ^= (x >> 24) & 255;
if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
}
// Mix in the current time (w/milliseconds) into the pool
function rng_seed_time() {
rng_seed_int(new Date().getTime());
}
// Initialize the pool with junk if needed.
if(rng_pool == null) {
rng_pool = new Array();
rng_pptr = 0;
var t;
if(typeof(navigator) != 'undefined' && navigator.appName == "Netscape" && navigator.appVersion < "5" && typeof(window) != 'undefined' && window.crypto) {
// Extract entropy (256 bits) from NS4 RNG if available
var z = window.crypto.random(32);
for(t = 0; t < z.length; ++t)
rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
}
//First try to use browser's PRNG over Math.random
try{
var crypt_obj = null;
if (typeof(window) != "undefined" && typeof(window.crypto) != "undefined") {
crypt_obj = window.crypto;
} else if (typeof(window) != "undefined" && typeof(window.msCrypto) != "undefined") {
crypt_obj = window.msCrypto;
}
if(typeof(crypt_obj) != 'undefined' && typeof(crypt_obj.getRandomValues) == 'function') {
if(rng_pptr < rng_psize){
var num = Math.floor((rng_psize - rng_pptr) / 2) + 1;
var buf = new Uint16Array(num);
crypt_obj.getRandomValues(buf);
for(var i = 0; i < buf.length; i++){
var t = buf[i];
rng_pool[rng_pptr++] = t >>> 8;
rng_pool[rng_pptr++] = t & 255;
}
}
}
}catch(e){}
//Fall back to Math.random if needed
while(rng_pptr < rng_psize) { // extract some randomness from Math.random()
t = Math.floor(65536 * Math.random());
rng_pool[rng_pptr++] = t >>> 8;
rng_pool[rng_pptr++] = t & 255;
}
rng_pptr = 0;
rng_seed_time();
//rng_seed_int(window.screenX);
//rng_seed_int(window.screenY);
}
Window.crpto
是Web Cryptography API的一部分:
[Web Cryptography API] 规范描述了一种 JavaScript API,用于在 Web 应用程序中执行基本的加密操作,例如散列、签名生成和验证以及加密和解密。此外,它还描述了一个 API,供应用程序生成和/或管理执行这些操作所需的密钥材料。此 API 的用途包括用户或服务身份验证、文档或代码签名以及通信的机密性和完整性。
window.msCrypto
是微软对此的实现。
如果您使用受支持的浏览器,则此生成方法看起来是安全的(它与您的浏览器的 Web Cryptography API 实现一样安全)。如果不是,那么它似乎使用Math.random
不安全的当前时间播种 - 如果是这种情况,如果网页警告您会很好。
此页面显示浏览器对 Web Cryptography API 的支持的当前状态。