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[:])
}