Skip to content
Toolcroft

OAuth 2.0 PKCE Generator - Code Verifier & Challenge for S256

Developer Tools

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

1Generate

Create a random code_verifier (43–128 chars).

2Hash

Compute code_challenge = BASE64URL(SHA-256(verifier)).

3Authorize

Send code_challenge in the authorization request.

4Exchange

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

  1. The client generates a random code verifier (a high-entropy random string, 43–128 characters).
  2. The client computes the code challenge: BASE64URL(SHA256(code_verifier)).
  3. The authorization request includes code_challenge and code_challenge_method=S256.
  4. The auth server stores the challenge. When the client exchanges the code for a token, it sends the original code_verifier.
  5. 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.getRandomValues or 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.

Browse all developer tools