这是一个基本问题,但上下文特别是在JavaScript方面。鉴于Math.random
不具有加密安全性,当调用无法预测的特定次数时,结果是否仍然可以被认为是安全的?
因此,如果我使用window.crypto.getRandomValues
生成一个32位数字并选择其中一个数字作为迭代计数 - 调用Math.random
那么多次并使用最后一个结果,结果是仍然可以预测?
这样做的目的是生成一组介于0和1之间的安全随机数(不包括在内),而无法手动对Math.random
进行定位。
我最初的想法是结果不应该是可预测的 - 但我想确保我不会忽视一些至关重要的事情。
答案 0 :(得分:3)
这是一个简单的Math.random()风格的CSPRNG插件:
Math.randomer=function(){
return crypto.getRandomValues(new Uint32Array(1))[0] / Math.pow(2,32);
};
// usage demo:
alert(Math.randomer());
与不安全的random()不同,由于使用了crypto.getRandomValues,这段代码仍然会限速,但这可能是一件好事,你可以每秒获得几十KB。< / p>
答案 1 :(得分:1)
老实说,我不确定为什么要使用window.crypto.getRandomValues
之外的东西(或其等效的/dev/random
)。如果你计划&#34;伸展&#34;由于某种原因,它的输出很可能是你做错了。无论您的情况如何,在将此种子种子提供给客户之前,请不要将此种子硬编码到您的脚本中。即使您的.js
文件是在服务器端动态创建的,也是如此。这就好像你会将加密数据与加密密钥一起推送......在其根中消除任何安全性增益。
话虽如此,让我们按照你的思路来看待你的问题......
math.random
的输出是不安全的,因为它产生可预测的输出。含义:具有一系列输出,攻击者可以成功恢复状态以及它将产生的以下输出。使用来自window.crypto.getRandomValues
(或其Linux等效/dev/random
)的加密安全种子来播种它将不解决该问题。
作为一种安全方法,您可能需要查看ChaCha20,它是一种加密安全的流密码。它确实产生比math.random
更安全的输出,并且我在Github等人看到了ChaCha20的几个纯粹的香草实现。所以,使用更安全的东西&#34;比math.random
更难以在你的脚本中实现。种子ChaCha20与window.crypto.getRandomValues
(或其Linux等效/dev/random
)按照您的计划进行,并且您已设置。
请注意,我还没有潜入使用Javascript进行加密目的本身。这样做往往会引入攻击向量。这就是为什么当您的项目在线提供时,您(至少)需要HTTPS。我不得不跳过提及所有其他相关的挑剔...主要是因为你没有在你的问题中提到这些细节,而且还要防止这个答案过于宽泛/长久。在Security.SE上快速搜索可以启发您使用-Javascript-for-crypto相关问题。
最后但并非最不重要的是,我想回到我对初学者所说的内容,并指出您可以简单地使用window.crypto.getRandomValues
(或其等效的Linux {{1} })用于所有随机性目的。在大多数情况下,不这样做的速度提升是最小的。
加密很难......不要试图自己解决问题。即使对于Javascript,已经存在适用的解决方案:
/dev/random
请参阅,大多数现代浏览器都支持最少的CryptoAPI,允许您的客户从Javascript中调用/* assuming that window.crypto.getRandomValues is available */
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]);
}
- 这实际上是对系统obj.getRandomValues()
或{{1}的调用}。
如果你真的必须支持过时的浏览器,那么体面的polyfills可以缩小差距。但是,当涉及到安全性时,无论是使用旧浏览器还是#34;以及&#34;使用polyfills&#34;是一场等待出错的噩梦。相反,要专业并教育客户更容易升级到更新的浏览器这一事实,而不是选择polyfill及其附带的问题。
墨菲定律适用于此:当使用polyfills进行安全/加密时,出现问题的方法会出错!
最后,为了安全并且不使用polyfill只是为了支持一些过时的浏览器,最好不要忘记什么东西击中粉丝。浏览器更新将花费您的客户几分钟。一个失败的加密polyfill永远破坏你的声誉。记住这一点!