Math.random() 加密安全吗?

IT技术 javascript random cryptography
2021-02-12 00:46:12

JavascriptMath.random()在不同浏览器中使用的算法有多好可以用它来生成盐和一次性密码吗?

random我可以使用多少位

5个回答

不; JavaScript 的Math.random()函数不是加密安全的随机数生成器。您最好使用JavaScript Crypto Library的 Fortuna 实现,它是一个强大的伪随机数生成器(查看src/js/Clipperz/Crypto/PRNG.js),或者使用Web Crypto APIgetRandomValues

@Teoman 这就是我说“确定性”的原因。如果第一位提供有关后续位的信息,减少熵(只有像 LCG 这样非常差的 RNG 才会这样做),或者如果可以从其他信息(例如密码)中预测盐分,那么它是可预测的。即使是半体面的非加密 PRNG 也不是这种情况。
2021-03-20 00:46:12
好点,但同样,短密码 + 盐可能会成为彩虹表的牺牲品。在涉及密码学的地方,使用加密级 RNG 总是有利的。
2021-03-23 00:46:12
它实际上不必很短,可预测(如在 random() 中)使其成为字典/表攻击的一个很好的目标..
2021-03-31 00:46:12
但是,作为附录,您不需要加密安全的 PRNG 来生成盐。盐只需要是唯一的,并且是非确定性生成的。
2021-04-10 00:46:12
@Teoman 但是,盐和密码的长度与盐的来源无关。是的,加密安全通常是一个更安全的赌注。
2021-04-12 00:46:12

它根本不安全,并且在某些情况下是如此可预测,您可以重建 PRNG 的内部状态,扣除种子,从而可以使用它来跨网站跟踪人员,即使他们不使用 cookie,隐藏在洋葱路由等后面...

谢谢你的链接,这是一个很好的例子,浏览器的 PRNG 可能有多弱。
2021-03-19 00:46:12
我想链接的论文实际上是更通用的trusteer.com/files/...
2021-03-19 00:46:12
找到第一篇论文的新 URL 并链接它。
2021-03-21 00:46:12

截至 2013 年 3 月,window.crypto.getRandomValues是自 Chrome 11 和 Firefox 21 以来可用的“实验技术”,可让您获得加密随机值。另外,请参阅最新的 W3C Web Cryptography API草案中的getRandomValues

描述:

如果您提供基于整数的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]);
}

另外,JavaScript 的 Math.random 的随机性如何?指的是 2008年主要浏览器中的临时用户跟踪和跨域信息泄漏和攻击,其中讨论了 JavaScript Math.random() 函数如何泄漏信息。

更新:有关当前浏览器支持状态,请查看Modern.IE Web Crypto API部分,该部分还链接到ChromeFirefoxSafari错误报告。

可以在此处找到有关 Web Crypto API 状态的当前链接:developer.microsoft.com/en-us/microsoft-edge/platform/status/...
2021-03-30 00:46:12

因为您无法知道浏览器的确切实现(除了像您的企业内部网这样的封闭用户组),我通常认为 RNG 很弱。

即使您可以识别浏览器,您也不知道浏览器本身或任何其他浏览器的代理 ID 是否被操纵。如果可以,您应该在服务器上生成号码。

即使您在 JavaScript 中包含了一个好的 PRNG,您的服务器也无法知道来自客户端的请求是否来自未修改的脚本。如果该数字进入您的数据库和/或用作加密工具,则完全不信任来自客户端的数据。这不仅适用于有效性(您确实验证了来自客户端的所有数据,不是吗?)而且适用于随机性等一般属性。

Math.random()不是加密安全的。Veracode 也会指出这种情况

CWE-331(熵不足)

我们可以利用 SecureRandom 来实现类似的功能。

new SecureRandom().nextDouble();
SecureRandom() 方法在 JavaScript 中可用吗?
2021-03-21 00:46:12