Proof Key for Code Exchange (PKCE) is a mechanism often used with an OAuth2 Authorization Code Grant flow to provide an enhanced level of security when authenticating to an Identity Provider such as Microsoft Graph to get an access token. In order to use PKCE a code_verifier is generated along with a code_challenge. There are numerous examples available of how to do that but not using PowerShell. This blog post details generating PKCE codes with PowerShell using my PKCE PowerShell Module for use with an OAuth2 Authorization Code Grant flow.
PKCE helps mitigate the Authorization Code interception security attack whereby a malicious actor could intercept the Authorization Code and use it to obtain an access token. With PKCE without knowing the “secret” the malicious actor isn’t able to exchange the Authorization Code for an access token.
The process flow diagram below from Auth0 details the PKCE with Authorization Code Flow process very well. As OAuth is a standard this process flow is implemented by many IDentity-as-a-Service vendors including Microsoft with Azure Active Directory. I will be posting another post specifically on using this module for PKCE with Authorization Code to Azure AD.
Update: 22 Dec 2021 This post details using this PKCE Module to generate PKCE codes and perform an Authorization Code with PKCE Flow using PowerShell to authenticate and authorize against Azure Active Directory for Microsoft Graph access.
PKCE Codes PowerShell Module
My PKCE PowerShell Module works on both Windows PowerShell (5.1+) and PowerShell (6.x, 7.x) and contains one cmdlet “New-PKCE” that can;
- Generate both the code_verifier and the associated code_challenge
- For a valid code_verifier generate the code_challenge
- Generate a code_verifier of a user specified length as per RFC 7636
PKCE Code Generation Overview
RFC 7636 specifies that a code_verifier is;
- 43 to 128 characters in length
- allowed characters are a-z, A-Z, 0-9 and – _ . ~
A code_challenge is then generated by encrypting the code_verifier using SHA256.
Note: A plain option also exists where the code_verifier is resent as the code_challenge. But I will not be going into that. If you’re using PKCE please use the SHA256 option.
Module Installation
Install directly from the PowerShell Gallery (PowerShell 5.1 and above).
install-module -name PKCE
Import
Import the Module.
import-module PKCE
Example
Using New-PKCE to generate a code_verifier and code_challenge using the default 127 character length.
New-PKCE | FL
Output
code_verifier : WoBOriV4tDoK61KVPbWM71sk5maozuSXjxRUO2fu9zIQCoH0ExenrT7clYznp15CKLy8HnnXENGBw3SuZjM0T2vaUvVJBD7ThpD2XqkjdPyekAkYFs8b4cCFaxHgFOhO code_challenge : dKk5vCznfP9dqr7PPugOfq_cmyX1hEMzvdVT_x0ZRg0
Example
Use New-PKCE to generate a code_verifier and code_challenge with a length of 99 for the code_verifier.
New-PKCE -length 99 | FL
Output
code_verifier : yf82tm6q0Q9mgkFfxPXfRNyN4dhlDHrI9kKKsX5vAVhMLeW80LyutH3wx9bPh82wisluIBOsaR6Z7P0z5LMcqoOfJRayn7ZpTkD code_challenge : YOamaHC_iqRrIkSusU2FEMahO2BVJz1KZzEQ9o6j5kE
Example
Using New-PKCE to generate a code_challenge for a specified code_verifier.
New-PKCE -codeVerifier '0_EUVyNBjAFIAKg7xqw-3WC5xAZkx..~~xqndi4WRc1NCCEdXUScvCfDsVygmDQQ~eIZiVamZsQp3XhqL9TuH5~9U-BRBvI3KeOtalT.~uByhfTcGhnd9gHySopRaeLN' | FL
Output
code_verifier : 0_EUVyNBjAFIAKg7xqw-3WC5xAZkx..~~xqndi4WRc1NCCEdXUScvCfDsVygmDQQ~eIZiVamZsQp3XhqL9TuH5~9U-BRBvI3KeOtalT.~uByhfTcGhnd9gHySopRaeLN code_challenge : gewJaAUliqSe-nMhl48sutkX4ayfCtcPc-72jRnAPMA
Example
Generate a code_challenge and code_verifier and assign them to variables for use in an OAuth2 Authorization Code Grant flow.
$pkceCodes = New-PKCE $codeChallenge = $pkceCodes.code_challenge $codeVerifier = $pkceCodes.code_verifier $pkceCodes | FL $codeVerifier $codeChallenge
Output
code_verifier : n8bOz65bchiqsu5dW1JTRWBGWlkbmKUCXR5CRiUqrdqIBeSvTlOjS8i9xsgpVVMBXEgjNKDBKhFNDnzFa4yp87v3fZNgPA2MtFEIrtdjoRkvtmAwrj3uCcyf1A4h7ZGY code_challenge : T1nH0TteC6QN7p4upQ4GPT_x0nWCfKMrtTi5-mptrvg
n8bOz65bchiqsu5dW1JTRWBGWlkbmKUCXR5CRiUqrdqIBeSvTlOjS8i9xsgpVVMBXEgjNKDBKhFNDnzFa4yp87v3fZNgPA2MtFEIrtdjoRkvtmAwrj3uCcyf1A4h7ZGY T1nH0TteC6QN7p4upQ4GPT_x0nWCfKMrtTi5-mptrvg
Summary
On the surface generating a PKCE code_verifier is quite simple, but there are a few nuances. Nuances that once I had written it I knew I was going to need it over and over so have published it as a PowerShell module.
Source code is on GitHub here.