Private/New-PKCEChallenge.ps1
<#
.SYNOPSIS Generates a random URL-safe string of the given length for use as a code challenge. .DESCRIPTION The string is generated according to the rules outlined in RFC 7636 section 4.1. The string is URL-safe and may contain the following characters: A-Z, a-z, 0-9, and the special characters -._~. .PARAMETER Length The length of the code challenge string to generate. Defaults to 43. .PARAMETER Method The PKCE method to use. Currently, only "S256" is supported, which uses the SHA-256 hash function to generate the code verifier. .NOTES https://datatracker.ietf.org/doc/html/rfc7636#section-4.1 .EXAMPLE New-PKCEChallenge -Length 32 -Method "S256" .OUTPUTS A string of the given length suitable for use as a code challenge. #> function New-PKCEChallenge { [CmdletBinding()] param ( [int]$Length = 43, [ValidateSet("S256")] [string]$Method = "S256" ) $unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~" # Generate a random string based on unreserved characters and length $codeVerifier = -join ((1..$Length) | ForEach-Object { $unreservedChars[(Get-Random -Minimum 0 -Maximum ($unreservedChars.Length - 1))] }) Write-Verbose "PKCE code_verifier:`t$codeVerifier" # Convert the code verifier to bytes $codeVerifierBytes = [System.Text.Encoding]::ASCII.GetBytes($codeVerifier) # Create a SHA256 hash $sha256 = [System.Security.Cryptography.SHA256]::Create() $hashBytes = $sha256.ComputeHash($codeVerifierBytes) # Convert the hash to a base64 URL-safe string $codeChallenge = [System.Convert]::ToBase64String($hashBytes) $codeChallenge = $codeChallenge.Replace('+', '-').Replace('/', '_').Replace('=', '') Write-Verbose "PKCE code_challenge:`t$codeChallenge" return @{ CodeVerifier = $codeVerifier CodeChallenge = $codeChallenge CodeChallengeMethod = $Method } } |