【问题标题】:Is Math.random() cryptographically secure?Math.random() 在密码学上是安全的吗?
【发布时间】:2011-08-04 20:08:52
【问题描述】:

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

我可以从一个random 中使用多少位?

【问题讨论】:

    标签: javascript random cryptography


    【解决方案1】:

    Math.random() 不是加密安全的。 Veracode 也会用

    指出这一点

    CWE-331(熵不足)

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

    new SecureRandom().nextDouble();
    

    【讨论】:

    • JavaScript 中是否可以使用 SecureRandom() 方法?
    【解决方案2】:

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

    【讨论】:

    • 不过,作为附录,您不需要加密安全的 PRNG 来生成盐。盐只需要是唯一的,并且是不确定地生成的。
    • 好点,但同样,短密码+盐可能会成为彩虹表的牺牲品。在涉及密码学的情况下,使用加密级 RNG 总是有利的。
    • @Teoman 但是,盐的长度和密码与盐的来源无关。是的,加密安全通常是更安全的选择。
    • 它实际上不必很短,可预测性(如 random())使其成为字典/表攻击的一个很好的目标..
    • @Teoman 这就是我说“确定性”的原因。只有当第一个比特提供有关后续比特的信息,降低熵——只有像 LCG 这样的非常差的 RNG 才会这样做——或者如果可以从其他信息(如密码)中预测盐,它才是可预测的。即使是半体面的非加密 PRNG,这两种情况都不是。
    【解决方案3】:

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

    说明:

    如果您提供基于整数的TypedArray(即Int8ArrayUint8ArrayInt16ArrayUint16ArrayInt32ArrayUint32Array), 函数将用密码随机填充数组 数字。浏览器应该使用强(伪)随机数生成器。如果请求的长度大于 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]);
    }
    

    另外,How random is JavaScript's Math.random? 的答案是指 2008 年的 Temporary user tracking in major browsers and Cross-domain information leakage and attacks,其中讨论了 JavaScript Math.random() 函数如何泄漏信息。

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

    【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 感谢您的链接,这是一个很好的例子,浏览器的 PRNG 可能有多弱。
    • 我想链接的论文实际上是更通用的trusteer.com/files/…
    • 找到第一篇论文的新 URL 并链接。
    【解决方案5】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2013-06-28
      • 1970-01-01
      • 2015-11-05
      • 1970-01-01
      • 2017-10-18
      • 1970-01-01
      • 2014-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多