PKCE code_challenge Generator
In our previous articl, we explained the theory behind the Authorization Code with PKCE flow: Authorizing against a server that utilizes PKCE requires a code_challenge in the initial /connect/authorize request and the corresponding code_verifier in the subsequent /connect/token request.
While the PKCE specification supports two methods (SHA-256 (S256) and Plai), Entrypage.io requires the use of SHA-256. This ensures a higher level of security by preventing the verifier from being intercepted in plain text.
Generating a S256 code_challenge
Use the tool below to generate a cryptographically valid code_verifier and its associated code_challenge in the required S256 format. You can also use this tool to construct your HTTP requests for testing purposes:
1. Proof Key
2. Authorize Request
Generating the code_verifier “manually”
To generate a S256 code_verifier, one must follow these steps:
- Generate Random Bytes: Create a sequence of cryptographically strong random bytes (typically 32 bytes to result in a 43-character string).
- Base64URL Encode: Convert those bytes into a Base64URL encoded string. This means replacing + with -, / with _, and stripping any trailing = padding characters.
- Hashing (for the Challenge): To create the associated code_challenge, apply a SHA-256 hash to the verifier string and Base64URL encode the resulting binary hash.
Bash
Use openssl to handle the entropy and the hashing in a shell environment:
# Generate a 32-byte random verifier
export verifier=$(openssl rand -base64 32 | tr -d '=+/' | cut -c1-43)
# Generate the S256 challenge
export challenge=$(echo -n "$verifier" | openssl dgst -sha256 -binary | base64 | tr '+/' '-_' | tr -d '=')
echo "Verifier: $verifier"
echo "Challenge: $challenge"C#
In .NET, utilize the RandomNumberGenerator for the verifier and the SHA256 class for the challenge:
using System.Security.Cryptography;
using System.Text;
// 1. Generate Verifier
var bytes = new byte[32];
RandomNumberGenerator.Fill(bytes);
var verifier = Convert.ToBase64String(bytes)
.TrimEnd('=').Replace('+', '-').Replace('/', '_');
// 2. Generate Challenge (S256)
using var sha256 = SHA256.Create();
var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(verifier));
var challenge = Convert.ToBase64String(challengeBytes)
.TrimEnd('=').Replace('+', '-').Replace('/', '_');JavaScript
For browser-based applications, the Web Crypto API is the standard for secure random values and hashing.
// Helper for Base64URL encoding
const base64Url = (buf) => btoa(String.fromCharCode(...new Uint8Array(buf)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
async function generatePKCE() {
// 1. Generate Verifier
const verifier = base64Url(window.crypto.getRandomValues(new Uint8Array(32)));
// 2. Generate Challenge (S256)
const encoder = new TextEncoder();
const hash = await window.crypto.subtle.digest('SHA-256', encoder.encode(verifier));
const challenge = base64Url(hash);
return { verifier, challenge };
}