Is Math.random() cryptographically secure?

JavascriptRandomCryptography

Javascript Problem Overview


How good are algorithms used in Javascript Math.random() in different browsers? Is it okay to use it for generating salts and one-time passwords?

How many bits from one random I can use?

Javascript Solutions


Solution 1 - Javascript

Nope; JavaScript's Math.random() function is not a cryptographically-secure random number generator. You are better off using the JavaScript Crypto Library's Fortuna implementation which is a strong pseudo-random number generator (have a look at src/js/Clipperz/Crypto/PRNG.js), or the Web Crypto API for getRandomValues

Solution 2 - Javascript

It is not secure at all, and in some cases was so predictable you could rebuild internal state of the PRNG, deduct the seed and thus could use it to track people across websites even if they didn't use cookies, hid behind onion routing etc...

2022 edit since this answer still gets upvotes: use Crypto.getRandomValues if you need a cryptographic RNG in JavaScript

Solution 3 - Javascript

As of March 2013, window.crypto.getRandomValues is an "experimental technology" available since Chrome 11 and Firefox 21 that lets you get cryptographically random values. Also, see getRandomValues from the lastest W3C Web Cryptography API draft.

Description: > If you provide an integer-based TypedArray (i.e. Int8Array, > Uint8Array, Int16Array, Uint16Array, Int32Array, or Uint32Array), the > function is going fill the array with cryptographically random > numbers. The browser is supposed to be using a strong (pseudo) random number generator. The method throws the QuotaExceededError if the requested length is greater than 65536 bytes.

Example:

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]);
}

Also, an answer to How random is JavaScript's Math.random? refers to Temporary user tracking in major browsers and Cross-domain information leakage and attacks from 2008 which discusses how the JavaScript Math.random() function leaks information.

Update: For current browser support status, check out the Modern.IE Web Crypto API section, which also links to the Chrome, Firefox, and Safari bug reports.

Solution 4 - Javascript

Because you cannot know the exact implementation of the browser (except for closed user groups like for your business intranet) I would generally consider the RNG weak.

Even if you can identify the browser you don't know if the browser itself or any other browser's agent ID is manipulated. If you can you should generate the number on the server.

Even if you include a good PRNG in your JavaScript your server cannot know whether the request from the client originates from an unmodified script. If the number goes into your database and/or is used as a cryptographic tool it is no good idea to trust the data from the client at all. That is true not only for validity (You do validate all data coming from the client, don't you?) but also for general properties like randomness.

Solution 5 - Javascript

Math.random() is not cryptographically secure. Also Veracode will point this occurrence with

> CWE-331 (Insufficient Entropy)

We could make use of SecureRandom to implement similar functionality.

new SecureRandom().nextDouble();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongrepView Question on Stackoverflow
Solution 1 - JavascriptTeoman SoygulView Answer on Stackoverflow
Solution 2 - JavascriptBruno RohéeView Answer on Stackoverflow
Solution 3 - JavascriptKevin HakansonView Answer on Stackoverflow
Solution 4 - JavascriptDaniel BöhmerView Answer on Stackoverflow
Solution 5 - JavascriptDecKnoView Answer on Stackoverflow