Secure Random String Generation in JavaScript (Beyond Math.random)
Learn how to generate secure random strings in JavaScript using crypto.getRandomValues and crypto.randomBytes for passwords, API keys, and tokens.
Secure random strings power passwords, API keys, session tokens, verification codes, and many other security-critical features. This guide explains how to generate cryptographically secure random strings in JavaScript, going far beyond simple Math.random() snippets.
If you search for "random string JavaScript", you will still find many examples that look like this:
function generateToken(length) {
let token = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let index = 0; index < length; index += 1) {
const charIndex = Math.floor(Math.random() * characters.length);
token += characters[charIndex];
}
return token;
}This kind of function feels random, but it is not strong enough for anything related to security. The problem is not the loop or the character set, it is the use of Math.random(), which was never designed to be a cryptographically secure random number generator.
Math.random() is fine for UI effects, demos, and simple games, but it can be predictable in ways that matter for attackers. A determined attacker who can observe enough outputs and knows the underlying algorithm may be able to reconstruct the internal state and guess future values.
For any security-sensitive string you should always use a cryptographically secure pseudo-random number generator (CSPRNG). In modern JavaScript that means using crypto.getRandomValues() in the browser or crypto.randomBytes() in Node.js.
Here is a safe pattern for generating random strings in the browser using crypto.getRandomValues():
function generateSecureToken(length) {
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const alphabetLength = alphabet.length;
const randomValues = new Uint8Array(length);
window.crypto.getRandomValues(randomValues);
let token = '';
for (let index = 0; index < randomValues.length; index += 1) {
const charIndex = randomValues[index] % alphabetLength;
token += alphabet[charIndex];
}
return token;
}
console.log(generateSecureToken(32));This approach reads high-entropy random bytes from the browser's cryptographic API, then maps each byte into the desired character set. You can easily change the alphabet to include only digits, add symbols for stronger passwords, or remove ambiguous characters like 0 and O.
In Node.js you can use the built-in crypto.randomBytes() function to implement the same idea on the server side:
import crypto from 'crypto';
function generateSecureToken(length) {
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const alphabetLength = alphabet.length;
const randomBytes = crypto.randomBytes(length);
let token = '';
for (let index = 0; index < randomBytes.length; index += 1) {
const charIndex = randomBytes[index] % alphabetLength;
token += alphabet[charIndex];
}
return token;
}
console.log(generateSecureToken(32));Once you have a secure primitive, you can adapt it to many different use cases. For passwords you might favor longer strings and include symbols, while for API tokens you may prefer URL-safe characters only. You can also generate multiple tokens at once for batch operations.
Even with a strong CSPRNG there is always a theoretical chance of collision, but for reasonably long strings (for example 32 random characters from a large alphabet) the probability is astronomically small. If you need absolute guarantees, you can combine random strings with uniqueness checks in your database or add contextual information like user IDs and timestamps.
In addition to generating secure values, you should also follow best practices for storage and rotation. Passwords should be hashed using modern password hashing functions, and API keys or session tokens should be revocable and rotated periodically.
If you want to experiment with these patterns without writing all the boilerplate yourself, try the JavaScript Random String Generator tool on jsgenerator.com at https://jsgenerator.com/tools/random-string-generator. It lets you tweak length and character sets, uses cryptographic randomness under the hood, and shows ready-to-paste snippets for both browser and Node.js environments.
Try the JavaScript Random String Generator
Generate cryptographically secure random strings for passwords, API keys, and session tokens, then copy production-ready JavaScript snippets for browser and Node.js.
Open the JavaScript Random String Generator tool