我想做一些javascript和加密的实验,我很好奇随机函数的实现有多么不可预测。有人做过任何硬性测试吗?
显然,浏览器能够生成强随机性(对于ssl)。问题是他们是否允许javascript访问相同的力量。
答案 0 :(得分:15)
通常,随机函数的加密性不强,因为您需要确保使用加密伪随机数生成器。
通用随机函数通常不使用加密强生成方法,因为它们比简单生成方法花费的时间更长(例如,Yarrow比Mersenne Twister更复杂)并且需要仔细管理熵池,这不能保证Mozilla ,cstdlib等想要给你。
如果您需要访问加密强大的随机数生成器,我会考虑访问底层SSL实现(给定浏览器可能允许或不允许访问)。
答案 1 :(得分:14)
最近的浏览器公开了加密强大的window.crypto.getRandomValues()
。
还有一些JS库实现了强大的RNG,但没有getRandomValues()
,收集熵非常困难。它can be done from mouse & keyboard虽然可能需要很长时间。
Math.random()
在2008年的大多数浏览器中都很弱 - Amit Klein's paper进入了极好的细节 - 可悲的是,今天几乎一样弱。
更新:似乎几乎所有浏览器都在2015-2016切换到XorShift128+ - LFSR的快速变体调整为良好的统计属性,但加密也非常弱:https://lwn.net/Articles/666407/ , https://security.stackexchange.com/questions/84906/predicting-math-random-numbers。以下详细信息已过期。
Firefox使用了一个非常弱的“我们自己的自制LFSR”算法;自2006年以来,他们一直在讨论转向更强大的算法和熵源(bug 322529)。更新:2015年他们改用XorShift128 +。
2013年5月,他们至少将种子从当前时间切换到良好的熵源(bug 868860),同时消除(?)交叉标签泄漏。
Webkit使用弱快速算法(GameRand)since 2009,但是从强大的OS来源初始化的强RNG中种子since 2010(在每个上下文中)。 (我认为这是Safari使用的,但我可能对各种WebKit端口感到困惑......)
Chrome不会随机使用WebKit,在V8 {@ 3}}中也是如此。 Math.random()是否应该是强大的(a weak linear thing)。
没有一致意见不确定它是如何播种的。 V8具有SetEntropySource()钩子,但显然它只是bug 246054,而不是Chrome调用。如果没有调用,random()
用于播种。
国家成为每个背景introduced for unit testing,但这对弱播种来说并不是很有用。
Opera宣称它是in 2011和fixed in Jan 2009,他们的Math.random()在加密方面非常强大。
没有找到关于IE现在做什么的文档。他们在2008年的线性PRNG较弱(见论文)。 他们确实告诉Amit他们会在服务包中修复它,所以可能会在某个地方提出建议......
答案 2 :(得分:7)
我熟悉的每个JavaScript引擎不使用加密强RNG。
如果你需要在浏览器中提供良好的熵源(并且最好不经常需要它),我建议捕获鼠标移动数据并通过加密强哈希算法运行它。现有的程序,如Entropy Gathering Daemon(与gpg一起使用)可以作为如何实现这样一个系统的参考。
答案 3 :(得分:1)
我发现一个有趣的数据点是mozilla有一个javascript加密对象尚未完全实现。
答案 4 :(得分:1)
通常,您不能依赖javascript中的伪随机数生成甚至远程加密安全。您可以考虑使用熵收集系统实现自己的PNRG,或者使用hotbits等外部随机数源。