Skip to main content

Cryptographic Randomness in Password Generation

About 8 min read

The most critical factor determining the security of a password generator is the quality of the random numbers it uses. Even if a string looks random, an attacker can guess the password if the underlying random numbers are predictable. NIST SP 800-90A is the standard that defines requirements for cryptographic random number generators, and random numbers used for password generation must meet this standard. As of 2025, with the advancement of quantum computing, NIST is progressing post-quantum cryptography (PQC) standardization, and randomness security criteria may be revised in the future. This article provides a technical explanation of the types and quality differences of random numbers, and describes the secure random number generation method adopted by Passtsuku.com. Understanding this alongside the concept of password entropy reveals the essence of password strength.

The Danger of Math.random()

The easiest way to generate random numbers in JavaScript is `Math.random()`. However, this function must never be used for password generation. `Math.random()` is a pseudo-random number generator (PRNG) that deterministically generates number sequences from an internal state (seed value).

The specific problems with `Math.random()` are as follows:

  • Internal state is guessable: the internal state can sometimes be reverse-engineered from the output sequence
  • No cryptographic security guarantee: the ECMAScript specification guarantees nothing about randomness quality
  • Implementation varies by browser: the V8 engine (Chrome) uses the xorshift128+ algorithm, which is unsuitable for cryptographic purposes
  • Seed prediction: some implementations use timestamps as seeds, so if the generation time is known, the output can potentially be reproduced

Security researchers have demonstrated attack methods that recover the internal state from `Math.random()` output. Research published in 2015 showed that for the V8 engine's xorshift128+ implementation, the internal state could be fully recovered from just 64 consecutive output values. Passwords generated with `Math.random()` may look random, but they are merely predictable strings for attackers.

An often-overlooked point is that `Math.random()` outputs floating-point numbers between 0 (inclusive) and 1 (exclusive), internally using only 52 bits of mantissa. This means the maximum number of possible output values is 2^52 (approximately 4.5 × 10^15). Since cryptographic applications require 128 bits or more of entropy, `Math.random()` alone is fundamentally insufficient in bit count.

How CSPRNG Works

Random numbers suitable for password generation must be produced by a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG). A CSPRNG satisfies the following two properties:

  • Unpredictability: even knowing all past outputs, the next output cannot be predicted
  • Irreversibility: it is computationally infeasible to reverse-engineer the internal state from the output

A CSPRNG uses entropy sources collected by the operating system as its seed. Entropy sources include physically unpredictable events such as hardware electrical noise, mouse movements, keyboard input timing, and disk I/O timing. By processing this unpredictable data through cryptographic hash functions and block ciphers, high-quality random number sequences are generated.

Linux provides `/dev/urandom` and Windows provides BCryptGenRandom as OS-level CSPRNGs. These are reliable implementations with years of security auditing and proven track records. For the theoretical background of cryptographic random number generation, CSPRNG and cryptographic security design books (Amazon) are also helpful.

Web Crypto API: crypto.getRandomValues()

The standard way to use a CSPRNG in browser environments is the Web Crypto API's `crypto.getRandomValues()`. This API is standardized by the W3C and available in all modern browsers.

`crypto.getRandomValues()` directly calls the OS-provided CSPRNG to generate random numbers. This means you get cryptographically secure random numbers verified at the OS level, not a browser-specific algorithm.

The decisive difference from `Math.random()` is that `crypto.getRandomValues()` guarantees cryptographic security. It is computationally infeasible to infer the internal state from the output, and knowing past outputs does not allow predicting future ones.

However, `crypto.getRandomValues()` has constraints. The maximum number of bytes that can be obtained in a single call is limited to 65,536 bytes, and requests exceeding this will throw an exception. This limit is unlikely to be reached for password generation, but caution is needed for simulation purposes requiring large amounts of random numbers.

As a method for verifying random number quality, the statistical test suite defined by NIST SP 800-22 is widely used. This test suite includes 15 types of tests including frequency tests, runs tests, and linear complexity tests. The output of `crypto.getRandomValues()` passes all of these, while `Math.random()` output is known to fail multiple tests. For random number quality evaluation methods, NIST randomness testing and cryptographic evaluation books (Amazon) are also helpful.

Passtsuku.com's Random Number Generation Method

Passtsuku.com uses `crypto.getRandomValues()` for all steps of password generation. `Math.random()` is never used. This guarantees that each character of the generated password is selected based on cryptographically secure random numbers.

Guaranteeing Uniform Distribution

In addition to random number quality, Passtsuku.com also ensures uniformity in character selection. If the values returned by `crypto.getRandomValues()` are simply taken modulo the character set size, a slight bias occurs when the character set size is not a power of 2. For example, when random numbers in the range 0-255 are taken modulo a 62-character set (uppercase + lowercase + digits), the first 8 characters are selected with approximately 1.6% higher probability than others. Passtsuku.com employs rejection sampling to eliminate this bias, ensuring all characters are selected with perfectly equal probability.

Browser-Only Security

Passtsuku.com's random number generation and password generation are entirely completed within the browser. Generated passwords and random number seed values are never transmitted externally over the network. Since no server-side processing is involved, there is zero risk of interception on the communication path.

When choosing a password generation tool, it is important to verify what random number generation method it uses. Tools using `Math.random()` have security concerns, so choose a tool like Passtsuku.com that uses `crypto.getRandomValues()`.

Random Number Quality Self-Check List

When choosing a password generation tool, check the random number quality from the following perspectives:

  • Whether the tool uses `crypto.getRandomValues()` or an equivalent CSPRNG
  • Whether it is explicitly stated that `Math.random()` is not used
  • Whether the generation process is completed within the browser (client-side)
  • Whether bias elimination techniques such as rejection sampling are used for character selection
  • Whether the source code is public and the random number generation method can be verified

Passtsuku.com meets all of these conditions. By understanding the concept of entropy and grasping the relationship with hash functions, you can gain a deeper understanding of how random number quality affects password strength. For practical guidance on applying these principles, see how to create secure passwords and encryption basics. High-quality random numbers are what make passwords resistant to brute-force attacks.

Take Action Now

  1. Generate a password of 16 characters or more with Passtsuku.com and replace your current self-created passwords
  2. Verify that your current password generation tool uses crypto.getRandomValues() (or an equivalent CSPRNG)
  3. Use Passtsuku.com's strength meter to confirm that generated passwords have 80 bits or more of entropy
  4. Update your browser to the latest version to ensure access to the latest Web Crypto API implementation

Frequently Asked Questions

Is it safe to generate passwords with Math.random()?
No, it is not safe. Math.random() is not a cryptographically secure random number generator and its output patterns are predictable. Use crypto.getRandomValues() from the Web Crypto API for password generation.
What is the difference between cryptographically secure and regular random numbers?
Regular pseudo-random numbers are determined by a seed value, so knowing the seed reveals all outputs. Cryptographically secure random numbers use hardware entropy sources, making it computationally infeasible to predict future outputs from past ones.
How can I verify the random number quality of a password generator?
For open-source tools, check if they use cryptographically secure APIs like crypto.getRandomValues() or /dev/urandom. For closed-source tools, you can statistically verify by generating many passwords and checking for character frequency bias.

Was this article helpful?

Related Terms

XHatena