Guide
PKCE for OAuth: code verifier, S256 challenge and the full flow
OAuth 2.0 lets an application get access to your data at another service without seeing your password. In the authorization code flow, the user signs in at the provider, which then redirects back to the app with a short-lived code that the app exchanges for tokens. For apps that cannot keep a secret, such as mobile apps and single-page applications, that code can be stolen in transit. PKCE, Proof Key for Code Exchange (RFC 7636, pronounced “pixy”), closes the hole, and OAuth 2.1 requires it for all clients. This page produces the two values the flow needs and shows where each goes.
How it works
Before sending the user to the provider, the app makes a random code verifier and keeps it. It sends only a derived value, the code challenge, in the authorization request. When it comes back with the code, it also sends the original verifier in the token request. The provider hashes the verifier and compares the result with the challenge it stored. An attacker who steals the code does not have the verifier, and a hash cannot be reversed, so the stolen code is useless.
The allowed shape
The verifier must be between 43 and 128 characters long and use only the unreserved URL characters: letters, digits, hyphen, period, underscore and tilde. The recommended way is 32 random bytes encoded in Base64URL, which gives 43 characters. The page lets you generate a verifier of a chosen length, 64 being a good choice, from the secure random generator, and checks a verifier you paste for length and characters. A new verifier must be created for every authorization request.
A worked check
Press “Sample (RFC 7636 example)”. The verifier is dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk, taken from Appendix B of the RFC. The page computes the SHA-256 of its 43 ASCII characters, encodes it in Base64URL without padding, and shows the code challenge E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM with the method S256, which is exactly the value printed in the RFC. If your own library gives a different challenge for the same verifier, check that it hashes the ASCII text and not a Base64-decoded version, and that it strips padding.
The two requests
With an endpoint, client ID, redirect URI and scope filled in, the page writes the authorization URL, for example https://auth.example.test/authorize?response_type=code&client_id=my-client-id&redirect_uri=…&scope=openid+profile&state=RANDOM_STATE&code_challenge=E9Melho…&code_challenge_method=S256, and a curl command for the token request that carries code_verifier. Replace the state value with a fresh random string and keep checking it when the user returns, since PKCE does not replace it.
Choosing S256
Use S256 whenever the provider supports it. The plain method puts the verifier itself in the authorization request, where interception would reveal it, and exists only for clients that cannot compute a hash. Most modern providers require S256.
Limits
The page produces values for testing and learning, not for a production flow, where your own code should make a new pair for each request. It does not talk to any provider or perform the login. Everything is generated in the browser.
Related tools
- JWT Decoder reads the ID token you receive at the end of the flow.
- Hash Generator computes the SHA-256 that underlies the challenge.
- Base64 Encoder converts between Base64 and Base64URL.
- SAML Decoder helps with the older SAML sign-in protocol.
Checked against the current version of the PKCE Code Verifier and Challenge Generator on .

