OAuth PKCE Code Verifier & Challenge Generator
Make PKCE values and an authorization request, and check them against RFC 7636.
Try before you buy.
- Free preview: the start of each value and the first lines of each request, the verdict of a pair check, and the counts and first checks of a request you paste.
- Locked until you unlock it: download and copy.
- Unlock: Pro pass, ₹179 for 30 days or ₹79 for 1 week, a one-time payment that never renews. Unlock: Pro pass, $5.99 for 30 days or $2.99 for 1 week, a one-time payment that never renews.
Ways to unlock shows how to get the full result.
Printing this result is locked in the free preview.
New PKCE values
- code_verifier
- code_challenge
- code_challenge_method
- state
- nonce
Build the authorization request
Exactly as registered for the client: servers compare redirect URIs character by character.
One name=value per line.
Authorization request
Token request (curl)
Replace PASTE_THE_CODE_FROM_THE_REDIRECT with the code your redirect_uri receives. A confidential client also authenticates (client_secret_basic, private_key_jwt …).
Does this verifier match this challenge?
Check an authorization request
Parameters in the URL
| Name | Value |
|---|
Locked in the free preview. Opens the ways to unlock this result.
Locked in the free preview. Batch runs unlock with a pass.
Locked in the free preview. Query results unlock with a pass.
About the OAuth PKCE Code Verifier & Challenge Generator
PKCE (Proof Key for Code Exchange, RFC 7636) protects the OAuth authorization code flow: the app makes a secret code_verifier, sends its SHA-256 — the code_challenge — with the authorization request, and proves it holds the verifier when it exchanges the code for tokens. A stolen authorization code is then useless. RFC 9700, the OAuth security best current practice, makes PKCE mandatory for public clients and recommends it for every other client.
This page makes a verifier exactly as RFC 7636 recommends (32 random octets in base64url from your browser’s Web Crypto), its S256 challenge, and a random state and nonce. Type your client settings and it builds the authorization request URL and the token request as a curl command. It also checks whether a verifier matches a challenge — and names the usual mistake when it does not — and reads an authorization request you paste against RFC 7636 and RFC 9700. Nothing is sent anywhere: the requests are built and read in this tab.
Without a pass you see a free preview: the first characters of each value and the first lines of each request, every pair check’s verdict and the counts of a request check with its first checks. The whole values and requests, and copying or downloading them, unlock with a Pro pass.
How to use it
- Keep the defaults — 43 characters from 32 random bytes, S256, with a nonce — or choose another length, and press Generate.
- Open Build the authorization request and type your authorization endpoint, client_id, redirect_uri and scope. The request URL and the curl token request appear below, with notes on anything RFC 9700 would have you change.
- Send people to the URL; when your redirect_uri receives the code, put it into the curl command in place of PASTE_THE_CODE_FROM_THE_REDIRECT. With a pass or after unlocking this result, copy each value and request, or download the values as JSON.
- To debug a failing flow, choose Check a pair and paste the verifier and the challenge your app used, or Check a request and paste the authorization URL it sends.
Examples
code_verifier: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk · method S256
code_challenge: E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
Appendix B of RFC 7636. Use RFC 7636’s example under Check a pair loads it.
challenge: E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw+cM=
No match — the right SHA-256 hash, but in standard Base64 (with + / and = padding). PKCE needs base64url without padding.
One of the mistakes the pair check names; servers answer it with invalid_grant.
https://login.example.com/authorize?response_type=code&client_id=app&state=xyz
Problem: no code_challenge — public clients MUST use PKCE (RFC 9700 §2.1.1). Warning: the state is only 3 characters.
Common uses
- Testing a single-page app’s or a mobile app’s sign-in against an OAuth or OpenID Connect provider by hand, before the code is written.
- Finding out why a token request fails with invalid_grant: a challenge encoded with the wrong Base64, sent as plain, or computed from different bytes.
- Reviewing the authorization requests an app sends: PKCE present, S256, an unguessable state, no tokens or secrets in the URL.
- Explaining PKCE in a workshop with real values that match the RFC’s formula.
How PKCE works
- The app makes a fresh code_verifier for each authorization request: 43 to 128 characters from A–Z, a–z, 0–9 and
- . _ ~(RFC 7636 §4.1). - It sends code_challenge = BASE64URL(SHA256(ASCII(code_verifier))) and
code_challenge_method=S256with the authorization request (§4.2, §4.3). - With the authorization code it sends the code_verifier in the token request (§4.5).
- The server hashes the verifier and compares it with the challenge it stored; a mismatch fails with invalid_grant (§4.6).
Whoever intercepts the code — another app on the phone that registered the same redirect, a log, a browser extension — cannot redeem it, because the verifier never left the app.
state, nonce and PKCE
- state is a one-time value the app keeps for the browser session and checks on the redirect. RFC 9700 says a client may rely on PKCE’s protection against cross-site request forgery once it knows the server supports PKCE; if the server does not, state or nonce MUST be used (RFC 9700 §2.1, §4.7.1). Many apps also use state to return the visitor to where they were.
- nonce belongs to OpenID Connect: it travels into the ID token, and the app checks the ID token’s nonce claim against the value it sent (OpenID Connect Core 1.0, §3.1.3.7). OpenID Connect requires “sufficient entropy” for it; this page uses 128 random bits for both.
Mistakes the pair check names
- Plain sent as S256, or no
code_challenge_methodat all, which means plain (RFC 7636 §4.3). - Standard Base64 (
+,/,=padding) instead of base64url — the most common one. - The hash written in hex instead of base64url.
- Hashing the decoded bytes of a base64url verifier instead of its ASCII text.
- Spaces or line breaks copied with a value.
What RFC 9700 asks of a client
- Public clients (single-page and mobile apps) MUST use PKCE; it is RECOMMENDED for confidential clients.
- Use a challenge method that does not expose the verifier — today that is S256.
- Clients SHOULD NOT use the implicit grant (
response_type=token); usecodewith PKCE instead (§2.1.2). - Register exact redirect URIs: servers MUST compare them as exact strings, and only the port of a native app’s loopback redirect may vary.
- Authorization responses MUST NOT travel over unencrypted connections, so servers must not allow
httpredirect URIs, except a native app’s loopback redirect (§2.6).
Limitations
- The page builds and reads requests; it never sends them. To try a flow, open the authorization URL yourself and exchange the code with the curl command.
- A request check reads the request’s form. Whether your server enforces PKCE, accepts the redirect URI or knows the client can only be seen by running the flow.
- For production, your app must make a new verifier, state and nonce for every sign-in at run time. Values made here are for testing, debugging and learning.
- Confidential clients also authenticate in the token request (client_secret_basic, private_key_jwt and others); the curl command leaves that part to you.
Privacy
On this device: nothing is sent
Everything is made and read in this tab with your browser’s Web Crypto: no value, URL or setting is uploaded or stored. Only the choices of length, method and nonce are remembered in this browser.
Frequently asked questions
What do I get without a pass?
Without a pass, OAuth PKCE Code Verifier & Challenge Generator shows the start of each value and the first lines of each request, the verdict of a pair check, and the counts and first checks of a request you paste. Until you unlock it, the result can’t be downloaded or copied. A Pro, Premium or Ultimate pass, a one-time payment that never renews, unlocks the full result. The pricing page lists the passes and their prices.
Why S256 and not plain?
With plain, the challenge is the verifier itself, so anyone who sees the authorization request — in a log or a browser history — can redeem the code. RFC 7636 says a client that can use S256 MUST use it, and RFC 9700 recommends challenge methods that do not expose the verifier, which today means S256.
How long should the code_verifier be?
RFC 7636 allows 43 to 128 characters and recommends base64url-encoding 32 random octets, which gives 43 characters with 256 random bits. Longer verifiers are allowed; some libraries use 64 or 128 characters.
Can I reuse a code_verifier?
No. RFC 7636 has the client create a code_verifier for each authorization request, and the state and nonce are one-time values too. Generate new ones for every sign-in.
Do I still need state if I use PKCE?
RFC 9700 lets a client rely on PKCE’s protection against cross-site request forgery once it has made sure the authorization server supports PKCE. If the server does not support it, state or nonce MUST be used. State is still useful to bring the visitor back to the page they started from.
Why does my token request fail with invalid_grant?
Most often the challenge was encoded with standard Base64 instead of base64url, sent with = padding, sent as plain while the server expected S256, or the verifier in the token request is not the one that made the challenge. Paste both into Check a pair to see which.
Are the values random enough?
They come from your browser’s Web Crypto getRandomValues(), its cryptographically secure generator: 256 random bits for a default verifier and 128 for state and nonce. Random characters are drawn without bias (bytes that would favour some characters are drawn again).