PKCE Code Verifier & Challenge Generator
Generate an OAuth 2.0 PKCE code_verifier (a random 43-128 character string) and its code_challenge — base64url(SHA-256(verifier)) for S256, or the verifier itself for plain — per RFC 7636, using a CSPRNG in your browser.
Input
RFC 7636 requires 43-128 characters. Longer values give more entropy. Ignored if you set an override verifier below.
S256 is required by OAuth 2.1 and supported by every modern provider.
Both produce verifiers compliant with RFC 7636. Choose whichever your client library expects.
43-128 characters from A-Z a-z 0-9 - . _ ~ (RFC 7636 §4.1). Provide your own for a reproducible code_challenge, e.g. to test against a known value. Leave blank to draw a fresh random verifier each time.
Send code_challenge + code_challenge_method on the /authorize request, then send code_verifier on the /token request — the server hashes the verifier and checks it against the original challenge. Store code_verifier in sessionStorage (not localStorage) for the duration of the redirect and discard it after the token exchange. Everything here runs in your browser via a CSPRNG and SHA-256 — nothing is sent anywhere.
Output
Keep this secret. Send it on the /token request — it never appears in the authorization URL.
| Step | Value |
|---|---|
| No data yet | |
Guides
Generate an OAuth 2.0 PKCE code_verifier and its matching code_challenge — the two values behind Proof Key for Code Exchange (RFC 7636), the mechanism that stops an intercepted authorization code from being redeemed by an attacker. Set a verifier length, pick S256 or plain, and get a fresh, cryptographically random pair generated entirely in your browser.
What is PKCE, and why two values?
PKCE adds a secret to the OAuth Authorization Code flow so an intercepted authorization code is useless without it:
- Your client generates a random code_verifier and keeps it secret.
- It derives a code_challenge from the verifier —
base64url(SHA-256(code_verifier))forS256— and sends only the challenge in the authorization request. - After the user approves and the provider redirects back with a code, your client sends the original code_verifier (never the challenge) to the token endpoint.
- The server re-derives the challenge from the verifier it just received and checks it matches step 2. A stolen authorization code is worthless without the verifier that produced its challenge.
OAuth 2.1 requires PKCE for every client type — public (SPA, mobile, CLI) and confidential (server-side) alike — not just clients without a client secret.
How to use it
- Set Verifier Length — 43 to 128 characters (RFC 7636's allowed range). Longer means more entropy; 64 is a reasonable default.
- Pick a Challenge Method —
S256(SHA-256, base64url-encoded) unless testing the legacyplainmethod, where the challenge is just the verifier itself. OAuth 2.1 and every modern provider requireS256. - Choose a Verifier Charset — the full RFC 7636 unreserved set (letters, digits,
-,.,_,~) or the narrower base64url alphabet some libraries default to. Both are spec-compliant. - Optionally paste a Code Verifier override to get a reproducible
code_challengeinstead of a fresh random one — useful for testing against a known value. Leave it blank to generate a new random verifier each time. - Click Generate. Send
code_challenge+code_challenge_methodon the/authorizerequest, andcode_verifier— never the challenge — on the/tokenrequest.
code_challenge/code_challenge_method aren't secret; code_verifier is — hold it in memory or sessionStorage for the redirect's duration, send it once, then discard it. Never in localStorage, never logged, never in a URL.
Building a full authorization URL rather than just the PKCE pair? See the OAuth Authorization URL Builder, which bakes an optional PKCE challenge, state, and nonce into a complete redirect URL.
Frequently asked questions
Why is my code_verifier rejected as "invalid"?
Check its length (43-128 characters) and character set (only A-Z, a-z, 0-9, -, ., _, ~ — no +, /, or =, which is why it isn't standard base64). Anything outside those bounds violates RFC 7636 §4.1.
Can I reuse the same code_verifier across logins? Don't — treat each authorization attempt as needing its own fresh, unpredictable verifier, the same way you wouldn't reuse a password reset token. Generating a new one is free.
Is there ever a reason to use plain instead of S256?
Only for interoperability testing against a client that genuinely can't compute SHA-256 — not a realistic constraint today. Every mainstream identity provider rejects or discourages plain; default to S256.
Privacy
Verifier generation uses a cryptographically secure random number generator, and the S256 hash is computed locally — nothing is sent to, logged by, or stored on a server. Refresh the page and the values are gone.