In one sentence
PKCE (RFC 7636) has the OAuth client create a random code_verifier, send code_challenge = BASE64URL(SHA-256(code_verifier)) with the authorization request, and send the verifier itself when redeeming the code, so an intercepted code is useless; this tool generates and checks both values in your browser.
How do I use the PKCE Generator?
Pick a length, generate, then copy the code_challenge into your authorization request and keep the code_verifier for the token request.
- Choose a verifier length (64 is a good default).
- Copy the code_challenge and send it with
code_challenge_method=S256. - Store the code_verifier with the user's session, or in memory in a native app.
- When the code comes back, send
code_verifierto the token endpoint.
Paste your own verifier into the box to compute its challenge and validate its characters and length. The values are also saved in this tab's session storage so the Authorization URL Builder can reuse them.
How is the challenge computed?
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))), with no padding.
const data = new TextEncoder().encode(verifier);
const hash = await crypto.subtle.digest("SHA-256", data);
const challenge = btoa(String.fromCharCode(...new Uint8Array(hash)))
.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
Random characters come from crypto.getRandomValues, with rejection sampling so each of the 66 allowed characters is equally likely.
What are state and nonce for?
state ties the authorization response to the user's session (CSRF protection); nonce ties the OpenID Connect ID token to the request.
Each generated value is 32 random bytes in base64url (43 characters, 256 bits). The article on the state parameter in OAuth 2.0 explains how state, PKCE and nonce divide the work.
| Value | Sent in | Checked by | Stops |
|---|---|---|---|
| code_challenge / verifier | Authorization request / token request | Authorization server | Code interception and injection |
| state | Authorization request | Client, at the redirect | CSRF on the callback |
| nonce | Authorization request | Client, inside the ID token | ID token replay |
Is anything sent to a server?
No. All values are generated and hashed in your browser with the Web Crypto API.
Questions
How long should a code_verifier be?
RFC 7636 requires 43 to 128 characters from the unreserved set A-Z, a-z, 0-9 and - . _ ~. It recommends creating it from 32 random octets, which base64url-encodes to 43 characters. Longer is fine.
Should I ever use the plain method?
Only if the client truly cannot compute SHA-256, which is almost never the case today. With plain, the verifier itself travels through the browser, which removes most of the protection. Many servers only accept S256.
Do confidential clients need PKCE?
RFC 9700 requires PKCE for public clients and recommends it for confidential clients, because it also prevents authorization code injection. The OAuth 2.1 draft requires it for all clients using the authorization code flow.
How do I know the hash is correct?
Click Load RFC 7636 test vector. RFC 7636 Appendix B gives the verifier dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk and the expected challenge E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM; the tool shows whether its result matches.