Security

How to Generate Secure Random Passwords in Node.js

SyncTonight Team6 min read3 views0 likes

A surprisingly common mistake in generated-password code is reaching for Math.random() to pick characters. Math.random() is a fast, general-purpose pseudorandom number generator, not a cryptographically secure one — its output is predictable enough, given enough samples, that it should never be used anywhere security matters, including password generation, token generation, or anything else where unpredictability is the actual point.

Node.js has had a proper cryptographically secure random number generator built into its standard library for a long time: the crypto module. crypto.randomBytes(n) returns n cryptographically random bytes, sourced from the operating system's secure random number generator, which is exactly the foundation a real password generator needs.

Turning random bytes into a usable password means mapping those bytes onto whatever character set you want to allow — letters, numbers, symbols, or some subset. A common approach is generating enough random bytes, then using each byte (modulo the length of your allowed character set) to pick a character, though care is needed here to avoid modulo bias, where certain characters end up statistically slightly more likely than others if the character set size doesn't divide evenly into 256.

For most practical purposes, Node's newer crypto.randomInt(min, max) function handles this correctly for you, generating a uniformly distributed random integer in a range without the bias issues of a naive modulo approach — looping it to pick each character from your allowed set is both simpler and more correct than hand-rolling the byte-mapping logic yourself.

Password length matters more than character set complexity for actual security — a longer password drawn from a smaller character set is often stronger, in terms of the number of guesses an attacker needs, than a shorter password with forced complexity rules (one uppercase, one number, one symbol) that people tend to satisfy in predictable ways, like capitalizing only the first letter or appending '1!' at the end.

If you're building a password generation feature and want a reference for reasonable defaults — length, character set options, avoiding ambiguous-looking characters like 0 and O — our Password Generator uses crypto.getRandomValues() under the hood entirely client-side, and its settings panel is a reasonable starting point for the kinds of options worth exposing to users.

Found this helpful?

SyncTonight's tools and guides are free and always will be. If this post saved you some debugging time, a coffee goes a long way — no pressure, just appreciated.

☕ Buy me a coffee

Keep Reading

Also available

We also build websites.

Need a landing page, a full product site, or a custom web app built? We design and develop those too — same speed and no-nonsense approach you see here. Let us know what you're building.

Landing pagesFull websitesWeb appsSaaS MVPsDashboards
Let's talk about your project