OAuth PKCE Generator
Generate a cryptographically secure PKCE code verifier and S256 challenge, plus state and nonce, with the point of each one explained in the flow.
Runs locallyEverything happens in your browser. What you paste or drop here is never uploaded, logged or stored.
Use the tool
What PKCE actually protects against
In the authorization code flow, the identity provider hands your application a code through the browser, and the application swaps that code for tokens. The weak point is the handover: the code travels through a redirect, and redirects leak. On mobile, another app can register the same custom URI scheme and receive it. In a browser it can end up in a referrer header, a proxy log or browser history.
PKCE closes that. Your app invents a secret - the verifier - keeps it, and sends only its SHA-256 hash in the authorization request. When it later redeems the code it presents the verifier itself. An attacker holding a stolen code cannot redeem it, because they never saw the verifier and cannot derive it from the hash.
It was originally designed for mobile apps and is now recommended for every client type, public and confidential alike, by the OAuth 2.0 Security Best Current Practice.
Why the randomness matters more than the length
The verifier's entire value is that nobody can predict it. Generated from
crypto.getRandomValues - the browser's cryptographic source - a 64-character verifier
carries about 387 bits of entropy and is not going to be guessed.
Generated from Math.random, it looks exactly the same and is predictable from a handful
of prior outputs. That is not a theoretical concern: Math.random is seeded from
observable state and was never designed for this. A PKCE generator built on it removes the whole
protection while producing output indistinguishable from the real thing.
There is one more detail worth stating because it is so often skipped. Mapping random bytes onto the 66-character verifier alphabet with a modulo makes the first 58 characters slightly more likely than the rest, since 256 is not a multiple of 66. This page uses rejection sampling instead, so the distribution is genuinely uniform and the entropy figure shown is the real one.
state and nonce are not the same thing
All three get generated together and all three are random, which is why they get conflated. They solve different problems:
- PKCE proves the application redeeming the code is the one that requested it.
-
stateis CSRF protection for the redirect. Your app stores it and checks the returned value matches. Without it, an attacker can trick a victim's browser into completing a login with the attacker's account, quietly attaching the victim's subsequent activity to it. -
nonceis OpenID Connect specific. It is carried into the ID token so your app can confirm the token was minted for this request rather than replayed from another.
You want all three. PKCE does not replace state.
Generated locally, and single-use
Every value is produced in your browser and none is transmitted. Generate a fresh set for each authorization request - reusing a verifier or a state reintroduces exactly the replay and fixation problems they exist to prevent.
Frequently asked questions
Do I need PKCE if my client has a secret?
Yes. The Security Best Current Practice recommends it for confidential clients too. A client secret authenticates the application at the token endpoint; PKCE binds the authorization code to the request that produced it. They cover different steps.
What about the plain challenge method?
It sends the verifier itself as the challenge, so anyone who observes the authorization request has the secret. It exists only for clients that cannot compute SHA-256, which in practice is none of them. Use S256.
Where do I store the verifier between the two requests?
Somewhere tied to the user's session and not readable by other origins - session storage for a browser app, the OS keychain or in-memory for a native one. It is short-lived, so it does not need durable storage.
Is 43 characters really enough?
Yes. 43 characters from the 66-character alphabet is about 260 bits. The RFC sets that as the minimum for good reason. 64 is a comfortable default rather than a necessary one.
Are these values sent anywhere?
No. They are generated in your browser with the Web Crypto random source and stay there.
References
Related tools
Other Tools
Popular tools from across A2Z
Rate this tool
Was this tool useful? Your feedback helps us improve it.