🎲 Random Token & API Key Generator

Last updated: January 28, 2026

Random Token & API Key Generator

Cryptographically secure β€” generated by your browser's CSPRNG, never sent anywhere.

8 – 512 characters
1 – 50
β€” bits entropy
Charset sizeβ€”
Entropy/charβ€”
Total entropyβ€”
Token lengthβ€”

Every API, every auth system, every webhook endpoint eventually needs the same thing: a secret string that no attacker can guess. Yet developers regularly reach for Math.random(), truncated UUIDs, or timestamp-based strings β€” none of which are cryptographically secure. This guide covers what makes a token truly secure, how browsers generate them natively, and how to pick the right format for different deployment contexts.

Why Math.random() Is the Wrong Tool for Secrets

JavaScript's Math.random() uses a deterministic pseudo-random number generator (PRNG). Given the seed, an attacker can reproduce every value it will ever produce. In practice, the seed is often derived from process state or timestamp data that leaks through browser fingerprinting, timing side-channels, or server logs. Security researchers have demonstrated PRNG seed recovery in V8 β€” the same engine that runs Node.js and Chrome β€” with as few as a handful of observed outputs.

The correct alternative is window.crypto.getRandomValues() in the browser or crypto.randomBytes() in Node.js. Both draw from the operating system's entropy pool β€” hardware events, interrupt timing, thermal noise readings β€” collected and mixed by the kernel. This is the same source used by openssl rand and /dev/urandom. It is not reproducible from observed outputs.

Entropy: The Actual Security Metric

Token "length" is a proxy measure. What matters is entropy β€” the number of possible tokens an attacker would need to search through. Entropy in bits is calculated as:

entropy = log2(charset_size) Γ— token_length

A 32-character hex token uses a charset of 16 symbols, giving log2(16) = 4 bits per character, so 128 bits of entropy total. That is the widely accepted floor for tokens that need to resist brute-force search even with a massive GPU cluster. A 32-character alphanumeric token (62-symbol charset) delivers log2(62) Γ— 32 β‰ˆ 190 bits β€” meaningfully stronger.

The practical implication: do not judge security by how "random-looking" a token appears. A 16-character hex string that came from crypto is safer than a 64-character string from Math.random().

Choosing the Right Encoding for Your Use Case

Hex (0-9, a-f) produces the most widely compatible format. Every HTTP framework, every database, every terminal handles hex without escaping. The downside is density β€” only 4 bits per character, so a 128-bit token needs 32 characters. Hex tokens are the right choice for API keys stored in environment variables, database primary keys for secrets tables, and any context where you are unsure about downstream character handling.

Base64url (A-Z, a-z, 0-9, -, _) delivers about 6 bits per character. That means 128 bits of entropy fits in just 22 characters, and 256 bits in 43. The "url" variant replaces + and / from standard Base64 with - and _, making it safe to embed in URLs, JWT headers, query strings, and cookie values without percent-encoding. This is the format used by JSON Web Tokens, OAuth PKCE code verifiers, and most modern session ID schemes. If you are generating bearer tokens or session cookies, Base64url is the best default.

Alphanumeric (A-Z, a-z, 0-9) splits the difference β€” denser than hex, simpler than Base64url, no special characters whatsoever. Approximately 5.95 bits per character. This format is ideal when tokens will be typed by humans (license keys, one-time codes) or when the downstream system has regex validation that rejects non-alphanumerics. The optional "no ambiguous characters" filter (removes 0, O, l, 1, I) removes visually confusable characters for scenarios where tokens might appear in printed documentation or support tickets.

Modulo Bias: The Silent Flaw in Naive Token Generators

A common implementation mistake is taking a random byte and computing byte % charset.length directly. If the charset size does not evenly divide 256, some characters appear slightly more often than others. For a 62-character alphanumeric charset, the bias is small but measurable β€” characters at positions 0–5 appear with probability 5/256 instead of 4/256. Over millions of tokens, this statistical skew can be detected and exploited.

The correct fix is rejection sampling: discard any byte value that falls in the remainder region above the largest multiple of charset.length that fits in a byte. The tool on this page uses exactly this approach β€” it requests a batch of random bytes, skips any that would introduce bias, and continues until the required length is filled. The overhead is negligible: for typical charset sizes, fewer than 2% of bytes are rejected on average.

Prefixes: Making Tokens Self-Describing

GitHub, Stripe, and Anthropic all use a practice worth copying: prefix tokens with a short, fixed string that identifies the token type. ghp_ for GitHub personal access tokens, sk_live_ for Stripe secret keys, sk-ant- for Anthropic API keys. This prefix adds zero security value β€” it is not secret β€” but it adds enormous operational value:

  • Secret scanning tools (GitHub, GitGuardian, truffleHog) can detect leaks by scanning for the prefix pattern in source code, CI logs, and commit history.
  • Developers can identify a token's purpose and environment (live vs. test) at a glance.
  • Support teams can confirm a customer is using the right key type without seeing the actual secret.

The entropy of the token is unchanged because the prefix is not secret β€” only the random suffix matters. A 64-character alphanumeric suffix prefixed with sk_prod_ is still a 64-character secret.

Storage and Transmission Best Practices

Generating a secure token is only the first step. Storage matters just as much. API keys stored in plain text in a database are a single SQL injection away from full compromise. Best practice is to store only a hashed form β€” SHA-256 of the token β€” and compare hashes at validation time. The original token is shown to the user once and never stored again. Stripe and GitHub both follow this model.

In transit, tokens belong in HTTP headers (Authorization: Bearer <token>), not in URL query strings. URLs appear in browser history, server access logs, nginx logs, CDN logs, and Referer headers β€” all places where a plaintext token in the query string will silently leak. A token in the Authorization header is not logged by default in any standard HTTP server configuration.

Environment variables are the accepted standard for application-level storage of API keys and secrets β€” not config files, not hardcoded strings, not comments in code. Tools like Doppler, HashiCorp Vault, and AWS Secrets Manager formalize this by managing environment injection at deploy time without ever writing secrets to disk in plaintext.

Key Rotation and Expiry

Long-lived API keys are a liability. Any key that was ever transmitted, stored, or even briefly visible is a key that could have been compromised without your knowledge. A rotating key strategy limits the blast radius: keys expire after 90 days (or shorter for high-sensitivity contexts), forcing regular regeneration. Combined with a prefix that encodes the generation date (tok_20261231_), you can identify stale keys in seconds.

For session tokens, OWASP recommends expiry after 15–30 minutes of inactivity for sensitive applications, with absolute expiry after 8–24 hours regardless of activity. Browser CSPRNG-generated session IDs of at least 128 bits entropy meet these requirements trivially β€” the bottleneck is always policy, not generation quality.

FAQ

Is it safe to generate API keys in the browser?
Yes, as long as the generator uses window.crypto.getRandomValues() β€” the browser's CSPRNG backed by OS entropy. The token is generated entirely in your JavaScript runtime and never leaves your device. Avoid any online generator that sends your token to a server to 'generate' it, since that would mean the server operator sees every secret you create.
How long should my API key or token be?
Aim for at least 128 bits of entropy, which is the widely accepted minimum for brute-force resistance. In practice: 32 hex characters (128 bits), 22 Base64url characters (132 bits), or 22 alphanumeric characters (131 bits). For long-lived secrets like API keys stored in databases, 256 bits (64 hex or 43 Base64url characters) is a safer choice that future-proofs against improvements in computing power.
What is the difference between Base64url and regular Base64?
Standard Base64 uses + and / as its two non-alphanumeric characters and often adds = padding. Both + and / are special characters in URLs and must be percent-encoded if used in query strings or path segments. Base64url replaces + with - and / with _ and typically omits padding. This makes tokens directly embeddable in URLs, JWT headers, cookie values, and HTTP headers without any encoding transformation.
What does 'no ambiguous characters' mean and when should I use it?
Ambiguous characters are those that look alike in common fonts: 0 (zero) and O (capital o), l (lowercase L) and 1 (one) and I (capital i). Removing them reduces the character pool slightly (from 62 to 56 for alphanumeric), dropping entropy per character from ~5.95 to ~5.81 bits. Use this option when tokens will be read and typed by humans β€” license keys, recovery codes, printed OTPs β€” where a misread character causes support burden. For machine-to-machine API keys, leave this off to maximize entropy density.
Should I store API keys as plain text or hashed in a database?
Always store a hash, never the plaintext. The standard approach is: generate the token, show it to the user exactly once, store SHA-256(token) in your database, and discard the original. On each API request, hash the incoming token and compare to the stored hash. This means a database breach exposes only hashes, which cannot be reversed into working API keys. Stripe, GitHub, and Anthropic all follow this pattern.
Can I use this tool to generate tokens for production systems?
Yes. The generator uses window.crypto.getRandomValues(), which is the same entropy source used by openssl rand, /dev/urandom, and every production-grade secret generation library. There is no algorithmic difference between this tool and running node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" in a terminal. The only consideration is that you should generate tokens in a trusted environment β€” not on a shared or compromised device β€” since the entropy source is only as trustworthy as the operating system providing it.