Password

How Web Crypto API Enables Secure Client-Side Password Generation

By Karuvigal Engineering

In the modern web ecosystem, privacy is no longer just a feature—it's a fundamental requirement. Historically, generating cryptographically secure random values on the client-side was a fraught process, often relying on weak implementations or server-side calls that leaked user data. The Web Crypto API (specifically the `SubtleCrypto` and `Crypto` interfaces) changed everything, providing developers with low-level, hardware-backed cryptographic primitives directly in the browser. This technical exploration examines how the Web Crypto API enables secure, zero-trust password generation, why the 'SubtleCrypto' name matters, and how to implement a high-entropy generator that never sends a single bit of sensitive data across the network.

How It Works

  1. 1Hardware Entropy Harvesting: The browser requests raw randomness from the underlying Operating System's entropy pool (e.g., CSPRNG).
  2. 2Buffer Allocation: Typed arrays (Uint8Array or Uint32Array) are allocated in RAM to hold the raw binary entropy.
  3. 3Atomic Random Filling: The `window.crypto.getRandomValues()` method populates the buffer in an atomic, side-channel resistant operation.
  4. 4Character Mapping Logic: The raw bytes are transformed into human-readable characters using unbiased modulo arithmetic to prevent 'pigeonhole' distribution flaws.
  5. 5SubtleCrypto Hashing: If needed, the raw entropy can be further processed using SHA-256 or SHA-512 to create fixed-length, uniform digests.

Key Features

Hardware-backed CSPRNG (Cryptographically Secure Pseudo-Random Number Generator)
SubtleCrypto interface for SHA-256, HMAC, and AES-GCM operations
Typed Array support for memory-efficient binary processing
Non-deterministic entropy sourcing for maximum unpredictability
Zero-dependency implementation using native browser standards

When to Use This Tool

  • Zero-Trust Password Generation: Creating strong keys that are never transmitted to a central server.
  • End-to-End Encryption (E2EE): Generating local session keys for private messaging apps.
  • Client-Side Tokenization: Creating secure, unpredictable nonces for OAuth and OIDC flows.
  • Digital Signature Signing: Generating ephemeral keys for document or transaction signing in-browser.
  • Secure Game Logic: Ensuring random outcomes in browser-based games are not predictable by bots.

Why Choose Karuvigal?

Zero Network Latency
Absolute Privacy Guarantee
High Computational Speed
Hardware-Verified Entropy
Cross-Browser Interoperability

The Math.random() Security Crisis

For years, junior developers used `Math.random()` to generate passwords and 'unique' IDs. This is a critical security mistake. `Math.random()` is typically implemented as a Linear Congruential Generator or a Xorshift algorithm. These are 'predictable' generators. If an attacker can observe a few outputs of `Math.random()`, they can mathematically calculate the internal state of the generator and predict every future number it will produce. In contrast, the Web Crypto API's `getRandomValues` uses 'True' entropy from the OS, making it non-deterministic and cryptographically secure. At Karuvigal, we enforce a strict 'No Math.random()' policy for all security-critical logic.

SubtleCrypto: Why the Name?

The API is divided into two parts: `crypto` (for basic random values) and `crypto.subtle` (for everything else). The term 'Subtle' is a warning to developers. Cryptography is incredibly easy to get wrong. A small mistake in how you handle a salt or an IV (Initialization Vector) can render an entire encryption system useless. The `SubtleCrypto` name reminds implementation engineers that these are 'low-level' primitives. They don't provide a 'Save Password' function; they provide the raw polynomial math and bit-shifting logic that you must carefully assemble into a secure protocol.

Implementing an Unbiased Generator

Common mistake: `char = charSet[randomNumber % charSet.length]`. This introduces a mathematical bias because most random numbers aren't perfectly divisible by the charset length. This is known as 'Modulo Bias'. A secure generator must use a 'rejection sampling' method. If a random value falls outside the largest multiple of the charset that fits into the buffer type, the value is discarded and a new one is requested. This ensures that every character in your 'Strong Password' has exactly the same mathematical probability of being chosen, maximizing the actual entropy of the string.

// Secure Unbiased Character Selection
function getSecureChar(charset) {
  const maxVal = 256 - (256 % charset.length);
  let rand;
  do {
    rand = window.crypto.getRandomValues(new Uint8Array(1))[0];
  } while (rand >= maxVal);
  return charset[rand % charset.length];
}

Developer Tip

  • Always use rejection sampling to avoid modulo bias in your random generators.
  • Test your distributions using a Chi-Squared test to ensure true uniformity.

Vite, Next.js, and SSR Pitfalls

Because the Web Crypto API is a browser-only feature, implementing it in modern frameworks like Next.js requires careful handling. If your code tries to access `window.crypto` during a Server-Side Rendering (SSR) pass, it will crash. You must ensure that cryptographic logic only executes in a `useEffect` hook or a dynamic client-side component. For Node.js environments, you should use the `node:crypto` module, which provides a similar but distinct interface for server-side entropy.

Frequently Asked Questions

Ready to Try It?

Start using our free Password tool now

Open Password Tool