Compute PKCE Code Challenge
This guide explains how to compute the PKCE code_challenge from a code_verifier using the S256 method (SHA-256 + Base64URL without padding).
Algorithm
- Compute the SHA-256 digest of the code_verifier bytes
- Base64URL-encode the digest (use - and _ instead of + and /, and strip trailing =)
Sample Code
Javascript
import { createHash } from 'crypto'
export function codeChallengeFromVerifier(codeVerifier) {
  const sha256 = createHash('sha256').update(codeVerifier).digest()
  return sha256
    .toString('base64')
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '')
}
Java
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class PkceUtil {
    public static String codeChallengeFromVerifier(String codeVerifier) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(codeVerifier.getBytes(StandardCharsets.UTF_8));
            return Base64.getUrlEncoder().withoutPadding().encodeToString(hash);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-256 not supported", e);
        }
    }
}
Python
import base64
import hashlib
def code_challenge_from_verifier(code_verifier: str) -> str:
    sha256 = hashlib.sha256(code_verifier.encode('utf-8')).digest()
    return base64.urlsafe_b64encode(sha256).rstrip(b'=').decode('ascii')
PHP
<?php
function codeChallengeFromVerifier(string $codeVerifier): string {
    $hash = hash('sha256', $codeVerifier, true);
    return rtrim(strtr(base64_encode($hash), '+/', '-_'), '=');
}
Go
package pkce
import (
    "crypto/sha256"
    "encoding/base64"
)
func CodeChallengeFromVerifier(codeVerifier string) string {
    sum := sha256.Sum256([]byte(codeVerifier))
    return base64.RawURLEncoding.EncodeToString(sum[:])
}