Use secure random number generators, please

Introduction #

The current article is an introductory article about the practical usage of different generators in standard libraries of other languages. It is the reason we do not explore different pseudo-random algorithms.

The article tries to help avoid the most common issues of developers.

If you have to use a specific random algorithm, certified algorithms, or algorithm forced by your security team or developer’s collegium (for example, some security products and products with particular regulations), just use it.

Motivation #

I have seen a few real-world security issues related to the topic in projects I worked on.

Some news (I remember only one the newest of them, I heard about):

Knowing the creation date of an account, an attacker can try to brute-force the account password with a small range of passwords (~100) and gain access to it.

— donjon.ledger.com1

What random is #

On the one hand, random is a simple entity to understand. But on the other hand, a random value - is a value that someone cannot predict.

On the other hand, computer science did not solve the problem with the name “random”. All values generated by pseudo-random algorithms we name as “random”. All randomization algorithms are pseudo-random because they do not generate really random values.

Truly random number generators #

“truly random” is more or less a natural random number generator. Specific devices can generate these values. These devices use several techniques for generating entropy, such as atmospheric noise, reverse bias semiconductors and beam splitting (for example - Recommendation for the Entropy Sources Used for Random Bit Generation).

There is at least one service with APIs that can be used to generate “truly random” values:

Pseudo-random number generators #

In all languages I’ve seed before presented at least two different types of random number generators:

Pseudo-random number generator (PRNG) #

PRNG is a predictable number generator to specify custom “seed”.

Seed is a value that uses as a starting value for the following random values mathematically calculated from previously generated values.

It means that everyone who knows used seed can generate the same infinite sequence of numbers.

When to use #

  • We need to have predictable random values, and we save seeds between generated values
  • We write a performance-sensitive application, and we do not use random functions for sensitive data

When not to use #

  • Use this function NEVER, until you are sure you HAVE TO use it in your particular case

Small suggestion #

If you decide to use this random and you need to specify your custom seed. Use, please, something less predictable than the then-current timestamp in seconds.

Possible ideas (higher is better in my opinion):

  1. If you can use some secure random algorithm, but you decided to use a faster solution, then generate seed once by secure random and use the selected algorithm after that
  2. If you cannot use secure random at all, use different unique values from your node, like the PID of an app, timestamp in nanoseconds, IP address, mac address, etc. Combine as many unique values as you can
  3. Use, at least, UNIX timestamp in nanoseconds with PID

Cryptographically secure random number generator (CSPRNG) #

CSPRNG is also a pseudo-random number generator and mathematical. Still it uses more complicated rules and algorithms to make it challenging to predict random values.

These algorithms are usually suggested for “real” sensitive generated values. I’m not a security expert to contradict this statement, but I have a reason to add more rules for using secure random.

Usually, software engineers are not as familiar with security (I’m as well) as we think. So when developers write some feature, they think the particular random number will not affect safety. Still, it can affect it in the future.

When not to use #

  • Use a basic CSPRNG provided by a programming language whenever you need random bytes. You did not decide to use the faster one
  • Investigate more secure implementation in a language or external libraries, if you need a certified crypto-secure generator

When not to use #

From my perspective, there are only two reasons to stop using this solution:

  • Performance issues that require to switch to something faster
  • Platform limitations where no way to use this kind of generators

Summary #

Until developers are sure what they are doing (even better to get approval from the security team for a particular use case), I’d suggest using CSPRNG from a language.

In libraries, a good way would be to provide options between different random functions and specify crypto-random generators by default.

  1. First found website, because I remember the issue from the news ↩︎

  2. In some languages, this type of “random” is named as mathematical, for example, Golang math/rand, JavaScript and Java Math.random ↩︎