Javascript Math.random()
在不同浏览器中使用的算法有多好?是否可以用它来生成盐和一次性密码?
我可以使用一个random
多少位?
答案 0 :(得分:38)
都能跟得上; JavaScript的Math.random()
函数不是加密安全的随机数生成器。你最好使用JavaScript Crypto Library的Fortuna实现,这是一个强大的伪随机数生成器(看看src/js/Clipperz/Crypto/PRNG.js
),或Web Crypto API for getRandomValues
答案 1 :(得分:16)
根本不安全,在某些情况下是如此可预测,您可以重建PRNG的内部状态,扣除种子,因此可以使用它来跟踪网站上的人,即使他们没有使用cookie,躲在后面洋葱路线等...
http://landing2.trusteer.com/sites/default/files/Temporary_User_Tracking_in_Major_Browsers.pdf 2008年的一篇论文揭露了用户追踪浏览器弱PRNG的可能性
http://dl.packetstormsecurity.net/papers/general/Google_Chrome_3.0_Beta_Math.random_vulnerability.pdf一个较晚的(2009)Chrome漏洞,因为问题已众所周知
答案 2 :(得分:8)
截至2013年3月,window.crypto.getRandomValues是一种“实验性技术”,可用于Chrome 11和Firefox 21,可让您获得加密随机值。另外,请参阅最新的W3C getRandomValues草案中的Web Cryptography API。
说明强>
如果您提供基于整数的TypedArray(即
Int8Array
,Uint8Array
,Int16Array
,Uint16Array
,Int32Array
或Uint32Array
), 函数将以加密随机方式填充数组 数字。浏览器应该使用强(伪)随机数生成器。如果请求的长度大于65536字节,则该方法抛出QuotaExceededError。
示例:强>
var array = new Uint32Array(10);
window.crypto.getRandomValues(array);
console.log("Your lucky numbers:");
for (var i = 0; i < array.length; i++) {
console.log(array[i]);
}
此外,对How random is JavaScript's Math.random?的回答是指2008年的Temporary user tracking in major browsers and Cross-domain information leakage and attacks,其中讨论了JavaScript Math.random()函数如何泄漏信息。
更新:有关当前浏览器支持状态,请查看Modern.IE Web Crypto API部分,该部分还会链接到Chrome,Firefox和{{3}错误报告。
答案 3 :(得分:3)
因为你无法知道浏览器的确切实现(除了像你的业务内部网这样的封闭用户组),我通常会认为RNG很弱。
即使您可以识别浏览器,也不知道浏览器本身或任何其他浏览器的代理ID是否被操纵。如果可以,您应该在服务器上生成号码。
即使您在JavaScript中包含一个好的PRNG,您的服务器也无法知道来自客户端的请求是否来自未修改的脚本。如果数字进入您的数据库和/或用作加密工具,那么完全信任来自客户端的数据并不是一个好主意。这不仅适用于有效性(您确实验证了来自客户端的所有数据,不是吗?),还适用于随机性等一般属性。
答案 4 :(得分:1)
Math.random()
不具有加密安全性。此外,Veracode将使用
CWE-331(熵不足)
我们可以使用SecureRandom来实现类似的功能。
new SecureRandom().nextDouble();