javascript中的安全随机数?

javascript中的安全随机数?,javascript,cryptography,Javascript,Cryptography,如何在javascript中生成加密安全的随机数?例如,您可以使用鼠标移动作为随机数的种子,在onmousemove事件发生时读取时间和鼠标位置,将该数据提供给一个增白函数,您将拥有一些一流的随机数。不过,在使用数据之前,请确保用户已充分移动鼠标 编辑:我自己制作了一个密码生成器,我不能保证我的美白功能完美无缺,但不断地重新设定种子,我很确定这足以胜任这项工作:ebusiness.hopto.org/generator.htm Edit2:它现在可以在智能手机上使用,但只能在熵聚集时禁用触摸功能

如何在javascript中生成加密安全的随机数?

例如,您可以使用鼠标移动作为随机数的种子,在onmousemove事件发生时读取时间和鼠标位置,将该数据提供给一个增白函数,您将拥有一些一流的随机数。不过,在使用数据之前,请确保用户已充分移动鼠标

编辑:我自己制作了一个密码生成器,我不能保证我的美白功能完美无缺,但不断地重新设定种子,我很确定这足以胜任这项工作:ebusiness.hopto.org/generator.htm

Edit2:它现在可以在智能手机上使用,但只能在熵聚集时禁用触摸功能。Android无法以任何其他方式正常工作。

您可能想试试
它的一个实现是一个加密安全的随机数生成器。(看看src/js/Clipperz/Crypto/PRNG.js)。它似乎也将鼠标用作随机性的来源。

WHATWG讨论了如何将其添加到window.crypto对象。您可以阅读并检查和webkit错误(22049)

刚刚测试了以下代码以获得一个随机字节:

(函数(){
var buf=新的UINT8阵列(1);
window.crypto.getRandomValues(buf);
警报(buf[0]);

})();按照顺序,我认为你最好的赌注是:

  • window.crypto.getRandomValues或window.msCrypto.getRandomValues
  • sjcl库的随机词函数()
  • isaac库的随机数生成器(由Math.random作为种子,因此不是真正的加密安全)()
  • window.crypto.getRandomValues已经在Chrome中实现了一段时间,最近在Firefox中也实现了。不幸的是,InternetExplorer10及之前的版本没有实现该功能。IE 11有window.msCrypto,它实现了同样的功能。sjcl有一个很好的随机数生成器,可以从鼠标移动中获得种子,但总有一种可能,鼠标移动不足以为生成器种子,或者用户所在的移动设备上没有任何鼠标移动。因此,我建议有一个后备方案,在没有选择的情况下,您仍然可以得到一个不安全的随机数。我是这样处理的:

    function GetRandomWords (wordCount) {
        var randomWords;
    
        // First we're going to try to use a built-in CSPRNG
        if (window.crypto && window.crypto.getRandomValues) {
            randomWords = new Int32Array(wordCount);
            window.crypto.getRandomValues(randomWords);
        }
        // Because of course IE calls it msCrypto instead of being standard
        else if (window.msCrypto && window.msCrypto.getRandomValues) {
            randomWords = new Int32Array(wordCount);
            window.msCrypto.getRandomValues(randomWords);
        }
        // So, no built-in functionality - bummer. If the user has wiggled the mouse enough,
        // sjcl might help us out here
        else if (sjcl.random.isReady()) {
            randomWords = sjcl.random.randomWords(wordCount);
        }
        // Last resort - we'll use isaac.js to get a random number. It's seeded from Math.random(),
        // so this isn't ideal, but it'll still greatly increase the space of guesses a hacker would
        // have to make to crack the password.
        else {
            randomWords = [];
            for (var i = 0; i < wordCount; i++) {
                randomWords.push(isaac.rand());
            }
        }
    
        return randomWords;
    };
    
    sjcl是双重许可的BSD和GPL,而isaac.js是MIT,因此在任何项目中使用这两种技术都是完全安全的。正如在另一个答案中提到的,clipperz是另一个选项,但是出于任何奇怪的原因,它是根据AGPL获得许可的。我还没有看到任何人能够理解JavaScript库的含义,但我会尽量避免


    改进我发布的代码的一种方法可能是将isaac随机数生成器的状态存储在localStorage中,这样就不会在每次加载页面时对其重新设定种子。Isaac将生成一个随机序列,但出于密码学目的,种子至关重要。使用Math.random进行种子设定是不好的,但如果不是在每次加载页面时都必须使用Math.random,则至少不那么糟糕。

    首先,您需要一个熵源。例如,移动鼠标、密码或任何其他。但是所有这些来源都不是随机的,并且保证你有20位的熵,很少有更多。您需要采取的下一步是使用类似“基于密码的KDF”的机制,这将在计算上难以区分数据和随机数据。

    使用,如下所示:

    var random_num = new Uint8Array(2048 / 8); // 2048 = number length in bits
    window.crypto.getRandomValues(random_num);
    
    这是并使用操作系统的随机生成器(例如)。如果需要IE11兼容性,则必须通过
    var crypto=window.crypto | | window.msCrypto;加密。getRandomValues(..)
    尽管如此


    请注意,
    窗口.crypto
    API也可以,这可能是更好的选择。

    要从范围
    [0,1)
    中获取加密强数(类似于
    数学.random()
    ),请使用:

    let random=()=>crypto.getRandomValues(新的uint32数组(1))[0]/2**32;
    
    console.log(random());
    许多年前,您必须实现自己的随机数生成器,并使用鼠标移动和计时信息收集的熵对其进行种子设定。这是JavaScript加密的燃素时代。现在我们需要使用
    window.crypto

    如果您需要一个随机整数,这是一个不错的选择。它安全地生成一系列随机字节,然后将其转换为无偏随机整数

    const randomInt = require("random-number-csprng");
    (async function() {
        let random = randomInt(10, 30);
        console.log(`Your random number: ${random}`);
    })();
    

    如果你需要一个随机浮点数,你需要做更多的工作。不过,一般来说,安全随机性是一个整数问题,而不是一个浮点问题。

    你所说的“加密”到底是什么意思?使用Math.random()返回一个介于0和1之间的随机数。它在技术上是伪随机的,因为实际上没有(简单)生成真实随机数的方法。我想问题是需要一个适用于加密的随机数生成器。例如,许多语言默认实现的模RND不适用。@logic-@logic Artist--不,Math.random不是加密安全的。加密安全是一个标准术语,意味着价值是不可预测的,即使是对一个愿意投入大量时间和精力试图预测它或将其与随机数据区分开来的对手来说也是如此。另外,请参阅此处提供的有关该库的更多详细信息。很好的答案,不幸的是,它是根据AGPL授权的,我认为它与我的项目不兼容。截至2014年5月2日,Clipperz在提交时从AGPL迁移到BSD。这里有一个具有BSD许可证的加密库和一个随机数生成器:这似乎符合OPs要求。SJCL(斯坦福加密库)看起来是个不错的选择。他们发表了一篇论文,详细描述了他们如何生成加密随机数,以及他们的
    const randomInt = require("random-number-csprng");
    (async function() {
        let random = randomInt(10, 30);
        console.log(`Your random number: ${random}`);
    })();