JavaScript Math.random()函数设计为返回单个IEEE浮点值n,以使0≤n <1。众所周知(至少应该知道)输出不是密码安全的。大多数现代实现使用XorShift128 +算法,该算法很容易被破坏。由于人们在需要更好的随机性时错误地使用它并不罕见,因此为什么浏览器不将其替换为CSPRNG?我知道Opera至少会这样做*。我能想到的唯一理由是XorShift128 +比CSPRNG更快,但是在现代(甚至不是那么现代)的计算机上,使用ChaCha8或AES-CTR每秒输出数百兆字节将是微不足道的。这些通常足够快,以至于只有一个系统的内存速度才能使一个优化的实现成为瓶颈。即使在所有架构上未经优化的ChaCha20实现,ChaCha8的速度也要快两倍以上。

我知道不能将其重新定义为CSPRNG,因为该标准明确地不能保证密码使用的适用性,但浏览器供应商自愿这样做似乎没有不利之处。它将减少大量Web应用程序中的错误影响,而不会违反标准(它仅要求输出近似于最近的IEEE 754数字),降低性能或破坏与Web应用程序的兼容性。 >

编辑:一些人指出,即使标准说您不能依靠它来实现密码安全性,也有可能导致人们滥用此功能。在我看来,有两个相反的因素决定了使用CSPRNG是否会带来净安全利益:


错误的安全感-否则将使用window.crypto之类的为此目的而设计的功能的人数之多,而决定使用Math.random()是因为其恰好在其预期的目标平台上具有加密安全性,因此决定使用此功能。
机会安全-多少不知道并且仍然使用Math.random()来保护敏感应用程序的人,这些应用程序可以避免自己的错误。显然,最好对他们进行教育,但这并不总是可能的。

可以肯定地说,受到错误保护的人数将大大超过受过错误保护的人数。被误认为是一种错误的安全感的人。

*正如CodesInChaos指出的那样,既然Opera是基于Chromium的,那就不再是事实了。


几个主要的浏览器都有错误报告,建议用加密安全的替代方法替换此功能,但没有建议的安全更改登陆:


铬线程:https:// bugs。 chrome.org/p/chromium/issues/detail?id=45580
Firefox线程:https://bugzilla.mozilla.org/show_bug.cgi?id=322529

变化基本上与我的相符。反对它的论点从微基准测试的性能下降(对现实世界几乎没有影响)到误解和神话,例如错误的想法,即随着产生更多的随机性,CSPRNG随着时间的推移会变得越来越弱。最后,Chromium创建了一个全新的加密对象,Firefox用XorShift128 +算法替换了其RNG。 Math.random()函数仍然完全可以预测。

评论

评论不作进一步讨论;此对话已移至聊天。

说特征具有一定的质量意味着义务。义务产生成本,首先是履行义务,其次是使其保持最新状态,其次是当您发现自己没有履行义务时。当您必须提供安全功能时,尤其如此。

@forest机会安全?我从未想过有人会说的话。

性能也许?获得加密安全的随机值比伪随机值要占用更多的CPU资源。在设计游戏(使用C ++)时,我特别不得不选择一种提供出色性能的随机算法。

将性能XorShift128 +与ChaCha8进行比较只是性能问题的一部分。 CSPRNG必须准备好发射所有安全随机位之前,必须收集足够的熵。这可能会花费大量的时钟时间。

#1 楼

我在1990年代中期到后期是JScript的实现者之一,并且是ECMA委员会的成员,所以我可以在这里提供一些历史观点。


JavaScript Math.random()函数是设计为返回0到1之间的浮点值。众所周知(至少应该如此),该输出不是加密安全的


首先:许多RNG的设计API太可怕了。 .NET随机类可以以多种方式被滥用以产生相同数量的长序列的事实是可怕的。一种自然使用方式也是错误方式的API是“失败之坑” API;我们希望我们的API是成功的秘诀,自然方法和正确方法是相同的。

我认为可以说,如果我们知道现在所知道的,那么JS随机API就会有所不同。甚至将名称更改为“伪随机”之类的简单事情也将有所帮助,因为如您所述,在某些情况下,实现细节很重要。在体系结构级别上,有充分的理由使您希望random()成为一个返回代表随机或伪随机序列的对象的工厂,而不是简单地返回数字。等等。第二课,让我们记住1990年代JS的基本设计目标是什么。移动鼠标时,让猴子跳舞。我们认为内联表达式脚本是正常的,我们认为两到十行脚本块是常见的,而且有人可能在页面上写一百行脚本的想法确实非常不寻常。我记得我第一次看到一万行的JS程序,而我的第一个问题是向我寻求帮助的人,因为与他们的C ++版本相比,它是如此之慢,是“您疯了吗?!10KLOC JS ?! “

JS中任何人都需要加密随机性的想法同样疯狂。您需要猴子的动作来保证不可预测的加密强度吗?不太可能。

另外,请记住那是1990年代中期。如果您不打算这样做,我可以告诉您,就加密而言,这是一个与今天截然不同的世界...请参阅加密技术的出口。

我什至不考虑放置加密在没有得到MSLegal团队大量法律建议的情况下,将随机性强加到浏览器附带的任何内容中。我不想在世界上认为运输代码向该国敌人出口弹药的世界中,用十英尺高的杆触碰加密货币。从今天的角度来看,这听起来很疯狂,但这就是过去。


为什么浏览器不将其替换为CSPRNG?


浏览器作者不必提供不做任何更改的理由。改变会花费金钱,而且他们会从更好的改变中解脱出来。每次更改都会带来巨大的机会成本。

相反,您必须提供一个论据,不仅是为什么进行更改是个好主意,而且还为什么要最好地利用他们的时间。这是一个小小的改变。


我知道不能将其重新定义为CSPRNG,因为该标准明确不能保证适用于密码学使用,但这样做似乎没有任何缺点


缺点是开发人员仍处于无法可靠地知道其随机性是否为加密强度的情况,并且甚至更容易陷入依赖标准无法保证的属性的陷阱。提议的更改实际上并不能解决问题,这是设计问题。

评论


(不讨论话题)您是否介意提供参考:“。NET Random类可以以多种方式被滥用以产生相同数目的长序列是可怕的?”:我以前从未听说过,还是您?指的是经典的“在紧密的循环中创建一千个随机实例”?

– VisualMelon
18 Mar 15 '18:12



@VisualMelon:在一个紧密的循环中创建一千个实例是经典的。但是,当您同时在两个线程上使用一个Random实例时,也会出现故障模式。随机不是线程安全的,在某些情况下,竞赛可能导致它永远返回零!

–埃里克·利珀特
18 Mar 15 '18:36



@VisualMelon:还有更细微的场景。假设您有两个随机种子不同的随机实例。看起来还好吧?但是假设您随后以某种方式组合了Random的两个实例。也许您正在使用它们来产生一系列的模切辊,并将它们成对添加。两个序列是否以某种非随机的方式相互关联?这似乎是合理的。毕竟,他们“并行”运行相同的算法,只是种子不同。

–埃里克·利珀特
18 Mar 15 '18 at 18:41

我认为,到目前为止,这是最好的答案,尤其是从这样的权威来源获得的时候。除非有更好的答案,否则我将目前将此答案标记为已接受。

–森林
18 Mar 16 '18 3:35



@EricLippert我认为值得为C#的可滥用Random的答案添加一个具体示例。像这样的(伪)代码:while(某事){int rand = new Random()。nextInt(); doSomething(rand); }-之所以失败,是因为C#的Random使用当前时间和课程分辨率作为种子,因此,如果doSomething很快,您将获得序列中的第一个数字,无论该时间的种子是多少,一遍又一遍,而不是不同那些。 (我知道您知道这一点;我正在为那些没有使用Microsoft进行C#工作的人做解释)

–莫妮卡基金的诉讼
18 Mar 16 '18在21:39



#2 楼

因为实际上存在Math.random()的加密安全替代方案:

window.crypto.getRandomValues(typedArray)

这使开发人员可以使用正确的工具来完成这项工作。如果要为游戏生成漂亮的图片或掉落物品,请使用快速的Math.random()。当您需要加密安全的随机数时,请使用价格更高的window.crypto

评论


您为什么不使用安全随机函数进行战利品掉落?

–xDaizu
18 Mar 15 '18在11:15

@xDaizu因为不是每一个战利品掉落都是一个战利品盒,有人会用它来制作真实的彩票。

– DonFusili
18 Mar 15 '18 at 11:16

如果您的战利品需要加密保护,并且您正在使用客户端RNG生成战利品(而不是询问服务器“我得到了什么?”),您很可能在做错事。

–索伦
18 Mar 15 '18 at 12:51

这没有解决问题...森林正在询问为什么Math.Random()是按其方式实现的,而不是如何在Javascript中使用CSPRNG

– Qwerty01
18-3-15在16:02



更明确地说,如果您不信任用户,则window.crypto几乎没有用。在这种特定情况下,他们(或他们的用户代理或他们信任的任何代理)可以在执行之前简单地将其替换为()=> 0.42。这些实用程序使用户(而非您)能够建立安全性。

–橙色狗
18-3-15在16:10



#3 楼

JavaScript(JS)于1995年发明。



可能是非法的:1995年,密码术仍受到严格的出口管制,因此,良好的CSPRNG甚至可能不合法发行在浏览器中。

性能:从历史上看,CSPRNG(加密安全的伪随机数生成器)比PRNG慢得多,因此为什么默认情况下使用CSPRNG?

没有安全性心态:1995年,才发明了SSL。几乎没有服务器支持它,互联网由电话线组成,并且被用于公共论坛(BBS)和MUD。加密对于情报机构来说是一种东西。

不需要:Web应用程序还不存在,因为只是发明了JavaScript。它被设计为一种解释性(因而较慢)的语言,以帮助页面更加动态。默认情况下,对于随机函数使用慢速(几乎不存在)的CSPRNG绝对是没有道理的。

几乎不需要,事实上,别无选择:JavaScript没有甚至在2013年12月之前都拥有CSPRNG的受普遍支持的API,因此直到几年前,在Web应用程序中进行适当的加密几乎是不可能的。

一致性:与其更改现有功能的含义,不如说,他们用不同的名字做了一个新功能。您现在可以通过crypto.getRandomValues访问CSPRNG。

总结:遗留的,但速度和一致性也很强。不安全的PRNG仍然要快得多,因为您不能假定所有硬件都支持AES,也不能依赖于RDRAND的可用性或安全性。

就我个人而言,我认为是时候将所有随机函数与CSPRNG交换掉,并将更快,不安全的函数重命名为fast_insecure_random()之类的东西了。只有科学家或其他需要大量随机数进行模拟的人才需要使用它们,但是RNG的可预测性不是问题。但是对于具有二十年历史的功能来说,替代功能仅存在了四年(2018年),我可以理解为什么我们现在还没有到这一点。

评论


而且Javascript比大多数人认为的要古老得多。自从至少1997年(版本1.1)以来就一直使用math.random函数。在此之前,甚至没有人会尝试使用javascript中的密码学(SSL直到1995年才问世)。

– LvB
18年3月15日在11:18

我不同意最后一句话。尽管单独使用crypto.getRandomValues可能是一个更好的名字,但使用math.Random已经存在了很多年,例如math.RandomCrypto会是一个更好的选择,因为它会在任何不安全调用的旁边列出每当开发人员键入math.rando时,API列表和良好的自动完成功能都会同时启用这两个版本,这使他们更有可能意识到自己需要使用新版本时。

–丹在火光中摆弄
18 Mar 15 '18 at 13:56

从语义上讲,您的建议是错误的。您想要获得加密上合理的随机值。不能获得随机的加密函数/密码/等。此外,数学库仅与数学函数有关。 CSPRNG是一种加密功能,因此属于加密库。 (并且不要忘记添加标准需要所有不同引擎制造商的共识。)

– LvB
18 Mar 15 '18 at 14:29

@LvB我对函数使用不同的名称(math.RandomSecure?)甚至在crypto。*中实现,而在math。*下只有一个别名(现代js能够内联别名以避免不必要的开销功能调用以实现别名?)。但是由于人们使用大量不同的工具来编辑javascript,因此将旧名称作为新名称的第一部分使编辑人员能够向开发人员建议安全的随机源的可能性最大化。

–丹在火光中摆弄
18年3月15日在15:48

@DanNeely您正在尝试通过技术手段解决人为问题。 e.a.人们应该学习在哪里使用什么工具,而不是IDE使用一些便利功能来建议正确的工具。 (最好是拥有IDE而不是建议一个合适的IDE,但这取决于IDE)。它也不会帮助所有在浏览器/ vim / nano /记事本/石碑/打孔卡/或其他任何文本编辑器或直接输入方法中编写JavaScript的人。另外,您还需要聘请很多不容易说服的引擎开发人员。

– LvB
18年3月15日在16:15

#4 楼

这太久了,不能发表评论。

我相信您的问题有一个错误的前提:


在现代(甚至不是那么现代)的计算机上,使用ChaCha8或AES-CTR每秒可输出数百兆字节



您正在考虑使用交流电连接的计算机上的桌面浏览器或装有较大的honkin 10Ah电池的笔记本电脑

我们生活在一个越来越以移动为先的世界中,尽管如今的移动设备功能强大,但它们有两个重要的限制条件:热量和电池寿命。与可以轻松达到100C的台式机处理器不同,您无法将手从智能手机用户身上拔下来。手机电池通常只能容纳笔记本电脑的1/3(如果幸运的话)。根本没有充分的理由在不需要时增加额外的热量产生/功耗。

评论


我怀疑您是否注意到典型代码(甚至在移动设备上)的加密和非加密RNG之间的性能/功耗差异。您必须使用javascript编写蒙特卡洛模拟。我们正在谈论每个数字大约30个CPU周期。

– CodesInChaos
18-3-15在13:51



@CodesInChaos可能是正确的。在拨打该电话之前,我想查看分析数据(例如在CRPG的端口上)。但这是一个隐含的前提,即“现在计算机速度很快,所以无关紧要”。

–杰瑞德·史密斯(Jared Smith)
18 Mar 15'在14:21

@CodesInChaos人们用JavaScript编写了Monte Carlo Simulations。

–德里克·埃尔金斯离开东南
18年3月16日在5:35

@jb。我的观点是,加密RNG几乎可以满足任何用例的速度,因此应该是默认值。蒙特卡洛模拟是您可能希望以质量换取性能的少数情况之一。

– CodesInChaos
18年3月19日在16:13

@CodesInChaos鉴于Math.random()仅返回单独的浮点值并且必须为每个新值调用,因此这是获取蒙特卡洛模拟随机性的一种相当糟糕的方法,无论是否使用XorShift128 +或ChaCha 。同样,XorShift128 +的LSB是LFSR,对于这种仿真来说可能不是很好。

–森林
18 Mar 20 '18在5:40

#5 楼

更大的原因是Math.random()可以替代:请参见Philipp的答案。因此,无论谁需要强大的加密技术,都有可能使用,而那些不需要强大加密技术的人可以节省时间和(电池)电量。

但是,假设您问过:“为什么,即使有更强大的替代方法,开发人员是否不能以相同的方式更新Math.random(),即使random()成为getRandomValues()的派生产品,以便自动增强其中的许多应用程序?” -那么,我认为这真的没有信心可以回答,除非是那些做出决定的开发人员(更新:按照Fate的意愿,我们确实有这样的答案)。

在原则-正如您已经说过的-没有充分的理由。

此外,大多数开发团队都有大量积压的工作要做;甚至像这样的表面上很小的变化也需要测试,回归,并且违背黄金的“如果没有破裂,就不要修复”的规则,这是YAGNI准则的一种更强形式。

评论


我确定在Mozilla和Google跟踪器上已经对此进行了讨论。也许您可以提供一些链接来证明这一点?我只对“因为还没有人做到”感到满意,但是我想看到一些这样的例子,开发人员不必要地否定了​​这个想法。

–森林
18-3-15在7:18



拒绝投票是因为我认为这是可以回答的,并且以粗体显示该答案的摘要很愚蠢。

–吕克
18 Mar 15 '18在11:08

@Luc我已经修改了答案以阐明我的意思-并赞成Philipp的答案,我认为这是对所问问题的正确答案。

– Lerni
18 Mar 15 '18在11:58

#6 楼

随机数和密码随机位是完全不同的动物。它们甚至没有用于相同的目的。如果要在0到42之间均匀分配一个随机数,则需要一个没有明显模式的均匀分布。请注意,如果将较大的数字修改为较小的数字,则分配的分布不完全均匀。对于从mod 27取的0到31之间的随机数,该示例很容易看到。0到4的出现频率是5到31的两倍。

在您谈论密码随机性之前,熵的概念是甚至没有讨论。一点熵会使搜索空间加倍,以猜测数字(针对数字的预期用户)。

当您要求加密随机位时,您在要求N位熵。拥有非显而易见的模式还不够好,因为如果发现了生成该函数的函数(无论其卷积如何),那么从知道该函数的人的角度来看,实际上熵为0位。

一个很好的例子是类似Fortuna的伪随机数生成器。您使用第一个随机数的密钥(其中密码块是大数)对数字1进行加密,然后使用第二个随机数的密钥对数字2进行加密,依此类推。对于不知道密码密钥(K位密钥)的用户,一个完美的N位密码块将具有该块的N位熵。

如果从中扩展到一百万比特的伪随机数据,那么如果继续使用相同的密钥K,则仍然只有K比特的熵。换句话说:如果一本书,您知道一百万个比特是用K下的单个密码生成的,因此不要尝试猜测所有密码流比特。只需坚持猜测密钥并从中生成密码流即可。

因此,随机数生成器通常是一种密码,可以不断获得重新播种,并且具有更大的随机性。相比之下,一个简单的[0,1]随机数生成器的熵不能超过该数中的位数。并且通常具有的奇数分布也不完全是您想要的。当浮点数仅为32或64位时,加密需要数百位,并且算法本身带走了很多熵....假设您想要从[0..1]中均匀分布一些东西,而不是说由随机位组成的浮点表示。我什至不知道那会有什么分布。

#7 楼

您已经亲自回答了这个问题:


该标准明确不保证密码使用的适用性


因此,与其更改实现,

鉴于此,以及改变常用功能的实现的技术开销,以及事实是,开发人员应选择“为工作选择合适的工具”。已经是针对此问题的特定解决方案(请参阅@Philipps答案),没有令人信服的理由进行更改。

评论


为什么选择DV?匿名小票对任何人都没有用...

–richzilla
18年3月19日在10:34

我投票否决,因为这回答了另一个问题。自然,该标准不保证加密安全性。但是,我的问题专门涉及机会安全。这些标准不需要被触及。技术开销应该较低,因为浏览器已经链接到TLS库。我可能可以编辑一个浏览器,以将Math.random()库用于少于5行的diff。

–森林
18-3-22在5:17



#8 楼

编程语言设计需要考虑很多事情。浏览器功能非常强大,如今可以优化很多JavaScript。但是,当考虑嵌入式系统时,可能没有任何好的随机性来源。例如,有些微控制器在运行nodeJS(如)环境。

这种微控制器没有随机源,不能保证密码学上安全的随机数。因此,您将需要连接一些可以向引脚提供随机输入的设备,以实现一种编程语言,从而为随机数提供有力的保证。而且,您将需要相当多的知识来构建具有足够随机性的设备,并以适当的方式处理来自设备的输入。

评论


运行JavaScript的浏览器通常会提供一个很好的随机性来源,以提供TLS。正如我说过的那样,无需更改标准,也不必保证API将输出加密安全的随机性。

–森林
18年3月16日在4:21

如果API不能保证真正的随机性,那么作为开发人员,您不应依赖它。如果开发人员不依赖它,则无需实现它。想象一下,大多数浏览器在那里都具有真正的随机性。网站会在上面建立东西,因为它在那里。然后,下一个浏览器没有真正的随机性。哎呀另一个原因可能是,如果在每个不需要它们的API调用中输出真正的随机值,则会消耗更多的熵池并需要更多时间。

– allo
18年3月16日在8:28

@forest虽然确实可以将足够随机的128位密钥与足够好的加密原语结合使用,以生成比我们一生中任何人都可能需要的更多的加密安全伪随机数据,但是这里有很多警告。一个简单的事实是,在包括许多Linux内核在内的某些CSPRNG实现中,熵池并不是无限的资源,如果对它们进行足够困难的查询,熵池可能会被耗尽/耗尽。如果需要的话,鼓励人们使用/ dev / urandom之类的东西,而不是/ dev / random,但不要假装/ dev / random不会用完。

– CBHacking
18-3-17的1:03

@forest Pedantry没有成为您。熵池是自动补充的,但是声称它“永不耗尽”就好比说只要有一家杂货店就不能“耗尽”牛奶。同样,声称/ dev / random可能阻止的原因是“愚蠢的”和“传统”并没有改变这样的事实,即从其中读取的内容可能会任意长时间阻止,实际上已经观察到在没有用户的情况下对VM进行阻止交互或真正的硬件(尽管今天主机通常会将熵提供给VM)。对于浏览器,任何规范都要求非阻塞熵源吗?

– CBHacking
18 Mar 17 '18 at 2:08

@forest足够公平,但是行为仍然类似于客户端应用程序的熵“用尽”,并且我不会指望SHA1的原像抵抗能够持续太长时间,此时,非阻塞/ dev / random不再是“完全安全的CSPRNG”。至于浏览器,我讲的是JS API,而不是内核网络堆栈(不是浏览器!)使用TCP序列号的东西。显然,对于这个问题,浏览器不会使用阻塞池来实现Math.random(),只是因为这样做很愚蠢,并非没有可能。

– CBHacking
18-3-17的2:34

#9 楼

像其他人一样,我要指出Math.random()也不是密码安全的,因为通常不需要它。但是我会进一步争论说,除非您有充分的理由,否则将加密安全算法写入规范中是不明智的。

加密安全性意味着什么?好吧,总是有一个无聊的定义:“还没有人知道如何打破它。”但是,当有人破坏它时会发生什么呢?如果指定了CSPRNG,则还必须提供一种查询正在使用哪种算法的方法,或者以其他方式使其得以使用,以便最终用户可以确定自己所得到的。

这也可能会导致需要能够支持多个生成器,以便用户可以选择他们信任的生成器。这增加了极大的复杂性。 API中的1行功能突然变成了套件。

此外,当您开始谈论加密时,您开始谈论尝试在生成器中确保安全。您提到使用AES生成随机数:您的AES实现是否需要不受旁通道攻击的影响?当您编写一个专门用于提供加密保证的库时,问这个问题并不是所有不合理的事情。对于一个规范,这可能是非常不合理的。用规范的语言来表达对旁通道攻击的免疫力是非常困难的事情。

通过将其放入规格中,您取得了什么成就?大多数PRNG用户根本不需要加密保证,因此您只是在浪费CPU周期。那些希望获得密码保证的人可能会寻求一个支持这种密码学所需的全套功能的库,因此他们无论如何都不会信任Math.random()。剩下的就是您提到的人口统计信息:那些犯了错并且在不应该使用时使用了工具的人。好吧,我可以从经验中告诉您,主要的编程语言并不是寻找不会被错误使用的API的地方。他们充满了“如果执行此操作,这是您自己的错”的措辞。

此外,请考虑以下问题:如果您使用Math.random()并假设有加密保证,那么您将要付出的几率是多少在您的算法中的某个地方犯另一个致命的加密错误? CSPRNG Math.random()可能提供错误的安全感,并且我们可能会发现更多错误!

评论


显然,您不应将其用作假定的加密属性。如果需要,可以使用专用的加密API(这也是为什么我建议使用ChaCha8而不是完整轮次ChaCha20的原因。请注意,可以对7个轮次ChaCha执行加密中断)。

–森林
18 Mar 17 '18 at 0:29

请参阅我对原始问题的编辑,以澄清此问题。

–森林
18 Mar 19 '18 at 4:26

@forest我看到您的编辑,并且我认为我的最后一段仍然有效。如果有人因为幸运而认为他们的软件是安全的,而其他人却对他们的安全性有所考虑,那么他们就处于粗鲁的觉醒之中。

–Cort Ammon
18 Mar 19 '18 at 15:05

#10 楼

这里的每个人似乎都错过了一些细微差别:加密算法要求数字在算法的所有执行过程中在数学和统计上都是随机的。这意味着,例如在游戏或动画中,您可以使用psuedorandom序列的数字,这对于“种类随机”的数字将是非常好的。

如果可以操纵该数字或预测的,例如种子随机数(这是Windows随机函数的默认行为),则该种子实际上是可预测的。如果我可以操纵您的应用程序以重新启动,然后使用带有种子的随机数,那么我可以预测您会选择哪种“随机”数。如果有可能,则可以取消加密。第二个关注点可能是某些算法需要保证频谱上的数字分布,而某些伪随机数生成器无法保证这种分布。

密码随机数生成器具有大量输入来创建熵,例如测量来自麦克风输入,一天中的滴答声,内存寄存器的校验和,序列号等的散粒噪声。如果不是不可能的话,尽可能多的输入使其难以操作和预测。从密码学的角度来看,性能不是目标,而是“真正”的随机性。

因此,根据您的用例,您可能希望对随机数进行合理的随机,高性能实现,但是如果您要diffie-hellman密钥交换,您需要一种加密安全的算法。

#11 楼

我没有看到任何人提到(或我只是忽略了)的另一个考虑因素是,Math.random()函数的某些用途实际上在播种时与以前相同时取决于可重复性。现在更改它会破坏这些用途。

评论


所有确定性PRNG都会这样做,无论是否通过密码保护。

–森林
18 Mar 24 '18在2:38

哪些浏览器具备种子生成器的功能?

–丹达维斯
19年8月27日在20:14