🍱 Lunchbox Hands

API Key Generator

Generate secure API keys and secrets in various formats

Generate cryptographically secure API keys and secrets. Choose from hex, base64, UUID, alphanumeric, or prefixed formats. Bulk generate and copy as .env variables. Everything runs locally using the Web Crypto API — your keys never leave your machine.

e.g. a1b2c3d4e5f6...

The five formats, and how much randomness each one holds

The strength of a random key is its entropy: characters × bits per character. Here is what each format actually produces, with the numbers at the default length of 32:

  • Hex — lowercase 0-9a-f, 4 bits per character. 32 characters = 128 bits.
  • Base64 — standard alphabet A-Z a-z 0-9 + /, 6 bits per character, no = padding. 32 characters = 192 bits.
  • Alphanumeric — A-Z a-z 0-9, about 5.95 bits per character. 32 characters ≈ 190 bits. No symbols, so it survives URLs, shell commands and double-click selection without quoting.
  • Prefixed — your prefix followed by alphanumeric characters, with the prefix counted inside the length. sk_live_ + 24 random characters ≈ 143 bits.
  • UUID v4 — from crypto.randomUUID(), always 36 characters. Only 122 of its 128 bits are random; the rest mark the version and variant. Good as an identifier, a little short on entropy compared with the others as a secret.

Length can be set from 16 to 128 characters, and you can generate up to 20 keys at a time. The tool doesn't add a checksum, doesn't register the key with any service, and keeps no history.

Why prefix a key at all?

A prefix like sk_live_ or sk_test_ costs nothing in security (it's not secret, and the random part still has to be long enough on its own) but buys several practical things. People can tell at a glance which environment a key belongs to, so a test key pasted into production fails loudly instead of quietly. Log scrubbers and secret-scanning tools can match a distinctive prefix with a simple pattern and catch a key leaked into a repository or a support ticket. And when you store only hashes of keys, keeping the prefix plus the first few characters in clear text lets your dashboard show "sk_live_Ab3…" so users know which key to revoke.

Worked example: two Stripe-style test keys for a .env file

Select Prefixed, change the prefix to sk_test_, set Length to 40, Env Variable Name to PAYMENTS_KEY and Count to 2, then click Generate. Reading the code, the output has this exact shape:

PAYMENTS_KEY_1=sk_test_ + 32 random characters from A-Z a-z 0-9
PAYMENTS_KEY_2=sk_test_ + 32 random characters from A-Z a-z 0-9

Each key is 40 characters long: 8 for the prefix plus 32 random ones, which is 32 × log2(62) ≈ 190 bits of entropy. Because Count is above 1, the variable names get _1 and _2 suffixes, and a Copy All (.env) button appears that copies both lines separated by a newline. The Env Variable Name field uppercases what you type and drops anything other than letters, digits and underscores, so payments-key becomes PAYMENTSKEY.

Hex and alphanumeric values need no quoting in a .env file. A base64 key can contain +, which is outside the character set every dotenv dialect agrees on, so quote it — the .env parsing differences post explains where the dialects split.

Related tools

To store a key safely, hash it with the hash generator and keep only the SHA-256. If what you need is a secret a human will type, the password generator adds symbols, per-character-class toggles and a strength meter. And if you're curious why the browser's crypto API matters here, is Math.random() random enough? covers the difference and the modulo-bias arithmetic quoted above.

Frequently asked questions

How long should an API key be?

Aim for at least 128 bits of randomness. In this tool that means 32 or more hex characters, or 22 or more alphanumeric or base64 characters (each of those carries about 6 bits). The default of 32 characters clears that bar in every format. The minimum length of 16 hex characters is only 64 bits, which is too little for a long-lived secret.

Are these keys really random?

Yes. Every format draws from crypto.getRandomValues (or crypto.randomUUID for UUIDs), the browser's cryptographically secure generator, not Math.random. Alphanumeric characters are picked with a 32-bit value modulo 62, which favours four characters by about one part in 69 million: measurable in theory, irrelevant in practice. Hex has no bias at all because 16 divides 2^32 evenly.

Is the base64 format safe to put in a URL?

Not as-is. It uses the standard base64 alphabet, which includes + and /. In a query string + can be read as a space, and / is a path separator. If the key will travel in a URL, pick hex or alphanumeric, or percent-encode it. The output never contains = padding, because the string is cut to your chosen length.

Does the prefix count toward the length?

Yes. In Prefixed mode the length is the total length of the key, so the default sk_live_ prefix (8 characters) at length 32 leaves 24 random alphanumeric characters, about 143 bits. If your prefix is longer than the length you set, you still get at least one random character, and the key comes out longer than requested.

Should I store API keys in my database as plain text?

No. Show the key to the user once, then store only a hash of it (SHA-256 is fine for high-entropy random keys) and compare hashes when a request comes in. Because these keys are long and random, they don't need a slow password hash such as bcrypt. Storing a short non-secret prefix alongside the hash lets users recognise which key is which.

Are the generated keys sent anywhere?

No. They are generated in your browser and exist only on this page until you copy them. Nothing is logged or stored, so if you navigate away without copying a key, it is gone.

Get weekly dev tools and tips