11

This question may be a little off-topic, but is Math.random the same as crypto.getRandomValues? (JavaScript)

Here's an example:

Math.random(); // 0.11918419514323941
self.crypto.getRandomValues(new Uint32Array(10))[0]; // 2798055700
(Using "self" for cross-site prevention)

They don't output the same number or nearly the same length, but I'm wondering if "crypto.getRandomValues" is more secure than "Math.random"?

A user told me (on this site) that I should use "crypto.getRandomValues" instead of "Math.random" for JavaScript security. All of this is for a JavaScript security project.

1

2 Answers 2

29

See MDN: Crypto.getRandomValues(), where it reads:

The Crypto.getRandomValues() method lets you get cryptographically strong random values.

(emphasis mine)

In contrast, see MDN: Math.random(), where it reads:

Note: Math.random() does not provide cryptographically secure random numbers. Do not use them for anything related to security. Use the Web Crypto API instead, and more precisely the window.crypto.getRandomValues() method.

(emphasis mine)

0
14

Your friend is correct; always use Crypto.getRandomValues instead of Math.random for anything related to security.

Math.random is designed for statistical simulations; and the numbers it produces are supposed to be randomly scattered around the number space. However, it is not designed to produce "unguessable" numbers, only numbers that are good for statistics. In other words, it doesn't matter in a simulation if your numbers have some internal pattern, or if you can repeat the random sequence.

The Crypto library, on the other hand, is designed to give numbers that are unguessable. They are not just random, but they have no identifiable relationship to each other. Learning a million random numbers output by it still won't reveal an inner pattern that helps you guess the next random value.

13
  • 4
    Creating unguessable numbers is a very hard problem for a computer. Every aspect of a computer is deterministic; they aren't designed to output different values when given the same inputs. It takes special effort to collect truly random event data to seed the Crypto random number generator. Commented Nov 12, 2021 at 20:21
  • 3
    @ParkingMaster The difference is when you have knowledge about how the RNG works. With any decent RNG, you won't see any pattern in the output. If you did, it would not look random in a statistical sense. The question is: knowing how the RNG works internally, can you deduce its internal state by looking at an output sequence? (Or rather: can you do it in reasonable computation time, using a reasonable output sequence length?)
    – Szabolcs
    Commented Nov 13, 2021 at 10:37
  • 2
    @Szabolcs “knowledge about how the RNG works” is a very misleading way to put it. I can tell you that my RNG is CTR_DRBG with this and that parameter, so you'll know everything about it except for the seed, and you still won't be able to predict its outputs. Conversely, if you're knowledgeable about the topic, you'll probably be able to predict outputs of a non-crypto RNG having seen a few hundreds/thousands/… outputs. The patterns in a non-crypto RNG are there if you know how to look at them. Commented Nov 13, 2021 at 13:55
  • 2
    @ParkingMaster The reason that it may seem that Math.random() returns a value that is greater in length than the value returned by Crypto.getRandomValues() is that Math.random() returns a decimal value between 0 and 1, whereas Crypto.getRandomValues() returns a 32 bit unsigned integer (i.e. an integer between 0 and 42949672965). If you do crypto.getRandomValues(new Uint32Array(1))[0]/4294967296 and compare to Math.random(), you'll see that they both return values that are the same in length.
    – mti2935
    Commented Nov 13, 2021 at 19:44
  • 1
    @mti2935 actually, that makes sense. Because Math.random returns 0.{some number} between one and zero, and like you said crypto.getRandomValues(new Uint32Array(10))[0]; returns a 32 bit unsigned integer. Commented Nov 13, 2021 at 19:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .