Take the 2-minute tour ×

How do I generate cryptographically secure random numbers in javascript?

share|improve this question
What exactly do you mean by "cryptographically"? Use Math.random() to return a random number between 0 and 1. Its technically pseudo random, since there isn't really any (simple) way to generate true random numbers. –  Logic Artist Nov 3 '10 at 0:16
I think the question is asking for a random number generator that is suitable for cryptography. Eg. The modulo RND implemented by default by many languages would not be suitable. –  winwaed Nov 3 '10 at 0:22
@logic - en.wikipedia.org/wiki/… –  Kyle Nov 3 '10 at 0:57
@Logic Artist -- No, Math.random is not cryptographically secure. Cryptographically secure is a standard term that means that the value is unpredictable, even to an adversary who is willing to invest a significant amount of time and energy trying to predict it or distinguish it from random. –  D.W. Sep 18 '11 at 3:36
Also see Insecure Randomness –  SyntaxRules Jun 4 '13 at 21:14

5 Answers 5

up vote 12 down vote accepted

You can for instance use mouse movement as seed for random numbers, read out time and mouse position whenever the onmousemove event happens, feed that data to a whitening function and you will have some first class random at hand. Though do make sure that user has moved the mouse sufficiently before you use the data.

Edit: I have myself played a bit with the concept by making a password generator, I wouldn't guarantee that my whitening function is flawless, but being constantly reseeded I'm pretty sure that it's plenty for the job: http://ebusiness.hopto.org/generator.htm

Edit2: It now sort of works with smartphones, but only by disabling touch functionality while the entropy is gathered. Android won't work properly any other way.

share|improve this answer
Here is a crypto library with a BSD licence, and a random number generator: crypto.stanford.edu/sjcl –  eBusiness Nov 3 '10 at 10:23
That does appear to meet the OPs requirements. –  GregS Nov 4 '10 at 0:18
SJCL (the Stanford Crypto Library) looks like an excellent choice. They have a published paper that describes in detail how they generate cryptographically random numbers, and their approach looks solid and well-thought out. –  D.W. Sep 18 '11 at 3:40
Awesome. Great answer! –  trusktr Oct 20 '12 at 19:09
I have a suggestion eBusiness: Add a delimitor field which would cause that string to be insterted between each .password span tag to make copying/pasting/manipulating easy. For example, currently, if I copy and paste the generated strings, they will be pasted as one long string. –  trusktr Oct 20 '12 at 19:36

There's been discussion at WHATWG on adding this to the window.crypto object. You can read the discussion and check out the proposed API and webkit bug (22049). Just tested the following code in Chrome to get a random byte:

(function(){var buf = new Uint8Array(1); window.crypto.getRandomValues(buf); alert(buf[0]) } )()
share|improve this answer
As of my reading works great on firefox and chrome, not IE. –  SyntaxRules Jun 4 '13 at 21:32

In order, I think your best bets are:

  1. window.crypto.getRandomValues or window.msCrypto.getRandomValues
  2. The sjcl library's randomWords function (http://crypto.stanford.edu/sjcl/)
  3. The isaac library's random number generator (which is seeded by Math.random, so not really cryptographically secure) (https://github.com/rubycon/isaac.js)

window.crypto.getRandomValues has been implemented in Chrome for a while now, and relatively recently in Firefox as well. Unfortunately, Internet Explorer 10 and before do not implement the function. IE 11 has window.msCrypto, which accomplishes the same thing. sjcl has a great random number generator seeded from mouse movements, but there's always a chance that either the mouse won't have moved sufficiently to seed the generator, or that the user is on a mobile device where there is no mouse movement whatsoever. Thus, I recommend having a fallback case where you can still get a non-secure random number if there is no choice. Here's how I've handled this:

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);
    // Because of course IE calls it msCrypto instead of being standard
    else if (window.msCrypto && window.msCrypto.getRandomValues) {
        randomWords = new Int32Array(wordCount);
    // 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++) {

    return randomWords;

You'll need to include sjcl.js and isaac.js for that implementation, and be sure to start the sjcl entropy collector as soon as your page is loaded:


sjcl is dual-licensed BSD and GPL, while isaac.js is MIT, so it's perfectly safe to use either of those in any project. As mentioned in another answer, clipperz is another option, however for whatever bizarre reason, it is licensed under the AGPL. I have yet to see anyone who seems to understand what implications that has for a JavaScript library, but I'd universally avoid it.

One way to improve the code I've posted might be to store the state of the isaac random number generator in localStorage, so it isn't reseeded every time the page is loaded. Isaac will generate a random sequence, but for cryptography purposes, the seed is all-important. Seeding with Math.random is bad, but at least a little less bad if it isn't necessarily on every page load.

share|improve this answer
I followed this approach at github.com/simbo1905/srp-6a-demo/blob/master/srp/Client/lib/… to create a random 128 hex number. It users window.crypto else isaac. If has to use isaac it will warm-up the generator onpageload by skipping randoms for 0.1s. The text input field onkeyup in also does random16byteHex.advance(Math.floor(event.keyCode/4)); to further skip forward random numbers for some milliseconds. That would make the isaac randoms used in that browser app depend on user input and hardware/browser speed so very hard to guess. –  simbo1905 May 21 at 21:40

You might want to try http://sourceforge.net/projects/clipperzlib/ It has an implementation of Fortuna which is a cryptographically secure random number generator. (Take a look at src/js/Clipperz/Crypto/PRNG.js). It appears to use the mouse as a source of randomness as well.

share|improve this answer
More detailed information about the library is available here clipperz.com/open_source/javascript_crypto_library –  ameer Nov 3 '10 at 0:29
Good answer, unfortunately it's licensed under the AGPL which I don't think is compatible with my project. –  Kyle Nov 3 '10 at 1:24

First of all, you need a source of entropy. For example, movement of the mouse, password, or any other. But all of these sources are very far from random, and guarantee you 20 bits of entropy, rarely more. The next step that you need to take is to use the mechanism like "Password-Based KDF" it will make computationally difficult to distinguish data from random.

share|improve this answer

Your Answer


