你能确保一个非加密安全的随机数发生器安全吗?

时间:2017-01-11 03:58:45

标签: javascript random

这是一个基本问题,但上下文特别是在JavaScript方面。鉴于Math.random不具有加密安全性,当调用无法预测的特定次数时,结果是否仍然可以被认为是安全的?

因此,如果我使用window.crypto.getRandomValues生成一个32位数字并选择其中一个数字作为迭代计数 - 调用Math.random那么多次并使用最后一个结果,结果是仍然可以预测?

这样做的目的是生成一组介于0和1之间的安全随机数(不包括在内),而无法手动对Math.random进行定位。

我最初的想法是结果不应该是可预测的 - 但我想确保我不会忽视一些至关重要的事情。

2 个答案:

答案 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相关问题。

而是 - 使用Web Cryptographic API

最后但并非最不重要的是,我想回到我对初学者所说的内容,并指出您可以简单地使用window.crypto.getRandomValues(或其等效的Linux {{1} })用于所有随机性目的。在大多数情况下,不这样做的速度提升是最小的。

加密很难......不要试图自己解决问题。即使对于Javascript,已经存在适用的解决方案:

Web Cryptographic API - 示例:

/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的最后几个字

如果你真的必须支持过时的浏览器,那么体面的polyfills可以缩小差距。但是,当涉及到安全性时,无论是使用旧浏览器还是#34;以及&#34;使用polyfills&#34;是一场等待出错的噩梦。相反,要专业并教育客户更容易升级到更新的浏览器这一事实,而不是选择polyfill及其附带的问题。

墨菲定律适用于此:当使用polyfills进行安全/加密时,出现问题的方法会出错!

最后,为了安全并且不使用polyfill只是为了支持一些过时的浏览器,最好不要忘记什么东西击中粉丝。浏览器更新将花费您的客户几分钟。一个失败的加密polyfill永远破坏你的声誉。记住这一点!