Randomness is a hard problem for computers. Most functions that generate randomness are **not** considered cryptographically secure. What this means is that it’s possible for attackers to take a good guess at what number a non-secure randomness generator generated. In the case of guessing a randomly generated private key, for example, this can be catastrophic.

Sorry for the interruption! I just wanted to mention that you should check out my new free cryptography course. It’s designed to teach you the crypto basics you need to get started in cybersecurity while writing code in the Go programming language.

## How to generate insecure random numbers

** Math.random()** is a built-in function in JavaScriptÂ that returns a floating-point, pseudo-random number in the range 0 to less than 1. By always generating a number between 0 and 1, you can scale the result up to whatever size you need.

### Example – Random number between 0 and 9

`const betweenOneAndTen = Math.floor(Math.random() * 10)`

Code language: JavaScript (javascript)

### Example – Random number between 10 and 100

```
const min = 10
const max = 100
const betweenOneAndTen = Math.floor(Math.random() * (max - min)) + min + 1
```

Code language: JavaScript (javascript)

## Why is Math.Random insecure?

Many non-secure randomness, or entropy, generators like `Math.Random()`

do something similar to the following:

```
function getRandom(timestamp, maxNumber){
// Take the deterministic hash of the timestamp
const hashedTime = sha256(timestamp)
// Reduce the hash to within the range [0, maxNumber)
return hashedTime % maxNumber
}
```

Code language: JavaScript (javascript)

This function (while ignoring some implementation details of modulus math by such a large number) will return random numbers that are based on the timestamp input, which is called the **seed**. If I pass in many different timestamps, the various outputs would **appear random**. This is an example of a weak **pseudo-random** number generator.

A weak pseudo-random number generator works perfectly fine if one is trying to:

- Create sample data for an application
- Write a video game engine
- etc …

However, weak pseudo-randomness can be **catastrophically dangerous** if one is trying to:

- Generate Bitcoin keys
- Generate passwords or salts
- etc …

## Use crypto.randomBytes() for cryptographically secure psuedo-randomness

Node’s built-in `crypto.randomBytes()`

function is a cryptographically secure random number generator that is based on openssl. Depending on the operating system of the user, `randomBytes`

will use `/dev/urandom`

(Unix) or `CryptoGenRandom (Windows).

While still pseudo-random sources, the important thing is that they are *not guessable* by an attacker. In other words, after using `crypto.randomBytes()`

to generate a secret key for AES-256 encryption, no one will be able to guess the key.

## Should I always use crypto.randomBytes()?

No. There are dangers if you implement your random number generator on top of a low-level API like random bytes. Because it returns bytes and not numbers, it’s up to you to convert the bytes into numbers. If you make a mistake, it can result in a vulnerability in your system.

In short, **use crypto.randomBytes()** whenever you need *raw bytes*. If you need a *number* within a range, for example, a random number between 0-9, then use a non-biased function that uses `crypto.randomBytes()`

as the source of entropy. For example: node-random-number-csprng

Ready to get coding?

## Have questions or feedback?

Follow and hit me up on Twitter @q_vault if you have any questions or comments. If I’ve made a mistake in the article, please let me know so I can get it corrected!

Salts are public information. What’s wrong if an attacker could predict future salts … ? How could they use that for anything malicious?

Or is there something more to do with it than to just predict future salts. Wouldn’t a PRNG be *good enough* for salting password/passphrases?

It appears obvious to me we shouldn’t use an incremental value: 1, 2, 3, … as a salt because that is too easily predictable. But if you have a PRNG with a decent output length, that is randomized somewhat, I don’t see how an attacker could compute rainbow tables for it practically.

For salts I agree it is less important, however for things like generating passwords/keys unpredictable entropy is a must.