http://thehobbyts.com/fun-dice-games-ultimate-list/

Randomness and Entropy in Node and Electron

Randomness is a hard problem for computers. For this reason most functions that generate randomness are not considered cryptographically secure. That means that it is possible that an attacker can take a good guess at what number a non-secure randomness generator generated.

How can randomness be attacked?

Many non-secure randomness (or entropy) generators would 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
}

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 psuedo-random number generator.

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

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

Weak psuedo-randomness can be catastrophically dangerous if one is trying to:

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

Strong Psuedo-Randomness (Cryptographically Secure)

A software-only system like Qvault can at best generate strong psuedo-random data because we are working on deterministic systems. Without an outside source of entropy (like someone rolling a dice and telling the computer each output) we are at the mercy of psuedo-randomness.

nodejs.org

crypto.randomBytes()

Node’s built in crypto.randomBytes 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 psuedo-random sources, the important thing is that they are not guessable by an attacker. In other words, after using crypto.randomBytes() to generate a recovery code in Qvault, an attacker can’t recreate that code.

What do I do?

In short, use crypto.randomBytes() whenever you need raw random bytes. If you need a random 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

Good luck, and always check the source!

Follow us on medium! https://medium.com/qvault

By Lane Wagner

Comments 2

  1. 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.

    1. Post
      Author

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

Leave a Reply

Your email address will not be published. Required fields are marked *