Sam Craig
May 4, 2023
Authentication Cryptography Data Security Encryption Privacy

Exploring CWE-335: Incorrect Usage of Seeds in Pseudo-Random Number Generator (PRNG)


The OWASP Top Ten list is a preeminent resource for application security. It describes the ten most common and impactful vulnerabilities that affect web applications today. In the latest version of the OWASP Top Ten list, Cryptographic Failures took the number two spot. This vulnerability describes the numerous ways in which cryptographic code could be used in ways that undermine its security.

Among these issues is the incorrect usage of cryptographic seeds for a pseudorandom number generator (PRNG), which is tracked as CWE 335. This issue makes it possible for an attacker to derive cryptographic keys and other sensitive values based on knowledge of the seed value.

Seeds and Cryptographic PRNGs

Cryptographic algorithms have numerous uses for random numbers. Ideally, private keys should be random to protect them from being guessed by an attacker. Other cryptographic parameters, such as initialization vectors (IVs) and password salts, may be public values, but they should be unpredictable.

However, while cryptographic algorithms need randomness, computers are poor at providing it. Computers are designed to be deterministic systems so that executing code has a predictable result. Any randomness in a program’s execution is an error to be handled, not a feature.

To generate the random values that cryptographic algorithms need, computers use cryptographically secure pseudorandom number generators (PRNGs). From an initial source of randomness, a cryptographic PRNG generates a series of values that are infeasible to guess without knowledge of this starting point.

This starting point is called a seed and contains all of the entropy or randomness used to generate the series of pseudorandom numbers. According to Kerckhoffs’ Principle, the PRNG algorithm should not be secret; only the seed is. If an attacker can guess or learn the seed used by a cryptographic algorithm, they can calculate the entire series of pseudorandom numbers generated, undermining the security of any encryption performed using them.

Where Seeding Goes Wrong

The seeds to a PRNG are critical to the security of private keys and other random inputs to an encryption algorithm. However, seed management can go wrong in various ways, such as:

  • Reused Seeds: Seeds to PRNGs should encode a certain level of entropy or randomness, which means that the seeds used for different sessions should be distinct. If seeds are hardcoded into an application or otherwise reused, then this increases the probability that an attacker could guess or otherwise learn the seed value.
  • Predictable Seeds: Cryptographic seeds should come from a strong source of randomness with a large number of potential values. Some common sources of seed values — while adequate for random values used for scientific purposes — create predictable values. For example, if an application uses the system clock as a seed, knowledge of the approximate time when the seed was generated makes it trivial for an attacker to guess the seed.
  • Poor Seed Security: A cryptographic seed is data at least as sensitive as the cryptographic keys that it is used to generate. Failure to properly protect this data could lead to the exposure of it and all of the values derived from it.

Case Study: keypair

keypair is a Javascript program for generating RSA private/public keypairs. In 2021, it was discovered that the tool often generated identical RSA private keys, which should have been impossible with RSA 2048 if implemented correctly.

The issue, tracked as CVE-2021-41117, was caused by several errors in the implementation of the tool for NodeJS environments, including:

  • Overloading crypto, so node’s CSPRNG is unavailable
  • Falling back to an RNG seeded with Math.random
  • Improperly encoding the result of the RNG

The end result of these errors is that each byte in the seed to the program’s counter-based CMAC PRNG has a 97% probability of being zero. For the 3% of non-zero cases, the value is between 1 and 9. As a result, the seed to the PRNG is easily guessable by an attacker. In fact, it is so weak that identical seeds are generated with sufficient frequency that identical keys are generated often enough to be noticed.

Properly Seeding Cryptographic PRNGs

The use of cryptographic PRNGs and random seeds is a workaround for the fact that computers are deterministic and poor at generating randomness. With a random seed, a deterministic computer can generate a series of values with high entropy for use in cryptographic algorithms.

When working with cryptographic PRNGs and managing cryptographic seed values, best practices include:

  • Use a strong source of randomness for seed values
  • Use a cryptographic library that offers a strong PRNG
  • Securely store seed values and destroy after use
  • When possible, use libraries that manage seed generation and storage

Up Next

To help build understanding of how cryptography can go wrong and how to fix it, we’ll continue to dive deep into prevention measures and most of the 29 CWEs related to OWASP’s A02:2021 – Cryptographic Failures vulnerability in a series of blogs. Each blog will describe the weakness, why it happens, a real-world case study, and recommended mitigations.

We’re very committed to improving the state of cryptography and data security by sharing knowledge and helping to correct common misconceptions about how cryptography works and how to use it properly. To keep up with this series and our other research and cryptography content, make sure to subscribe to our blog in the page footer below.

Get radically effective data-level protection. Get Ubiq.