Developer Tools
OAuth 2.0 PKCE Generator - Code Verifier & Challenge for S256
Generate OAuth 2.0 PKCE code_verifier and code_challenge (S256) pairs for public clients. Build the complete authorization URL with client ID, redirect URI, scope, and state.
Authorization URL Builder
Create a random code_verifier (43–128 chars).
Compute code_challenge = BASE64URL(SHA-256(verifier)).
Send code_challenge in the authorization request.
Send code_verifier when exchanging the auth code for tokens.
What is OAuth 2.0 PKCE?
PKCE (Proof Key for Code Exchange, pronounced "pixy") is a security extension to the OAuth 2.0 authorization code flow. It prevents authorization code interception attacks that could occur in public clients (single-page apps, mobile apps) that cannot securely store a client secret.
How PKCE works
- The client generates a random code verifier (a high-entropy random string, 43–128 characters).
-
The client computes the code challenge:
BASE64URL(SHA256(code_verifier)). -
The authorization request includes
code_challengeandcode_challenge_method=S256. -
The auth server stores the challenge. When the client exchanges the code for a token, it
sends the original
code_verifier. - The auth server re-hashes the verifier and compares it to the stored challenge. They must match.
Why it matters
Even if an attacker intercepts the authorization code, they cannot exchange it for a token because they don't have the code verifier. PKCE is now recommended for all OAuth 2.0 clients, including confidential server-side apps (RFC 9700).
Code verifier requirements
The code verifier must meet specific requirements per RFC 7636:
- Character set: URL-safe base64 characters only - A–Z, a–z, 0–9, hyphen (
-), period (.), underscore (_), tilde (~). - Length: minimum 43 characters, maximum 128 characters.
- Entropy: minimum 256 bits of cryptographic randomness (use
crypto.getRandomValuesor equivalent - never Math.random()).
These constraints exist to ensure the verifier cannot be guessed or brute-forced, even if the code challenge is exposed.
Integration code example
// Generate PKCE code verifier and challenge (Web Crypto API)
async function generatePKCE() {
// Generate 32 random bytes -> 43 base64url chars
const array = new Uint8Array(32);
crypto.getRandomValues(array);
const codeVerifier = btoa(String.fromCharCode(...array))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
// SHA-256 hash of the verifier
const encoder = new TextEncoder();
const data = encoder.encode(codeVerifier);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = new Uint8Array(hashBuffer);
const codeChallenge = btoa(String.fromCharCode(...hashArray))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
return { codeVerifier, codeChallenge };
} Comparison to implicit flow
The OAuth 2.0 implicit flow (now deprecated in RFC 9700) was designed for browser-based apps
that could not safely store client secrets. Instead of an authorization code, it returned
access tokens directly in the URL fragment (e.g., #access_token=abc123). This
exposed tokens in browser history, server logs, and referrer headers.
PKCE eliminates this attack surface by keeping the token exchange server-side (or at minimum, preventing its reuse without the verifier). All new OAuth implementations should use the authorization code flow with PKCE rather than the implicit flow.