Search code examples
identityserver4pkce

IdentityServer4 PKCE error: "Transformed code verifier does not match code challenge"


I cannot get IdentityServer4 PKCE authorization to work using Postman.

Using online tools I create the necessary parts:

Choose a random string:

1234567890

Get its SHA-256 hash:

c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646

Base64 encode the hash to get the code challenge:

Yzc3NWU3Yjc1N2VkZTYzMGNkMGFhMTExM2JkMTAyNjYxYWIzODgyOWNhNTJhNjQyMmFiNzgyODYyZjI2ODY0Ng==

In the browser I navigate to the following URL, fill in my credentials and retrieve the code from the fragmented redirect URL.

GET https://localhost:5000/connect/authorize
?client_id=pkceclient
&scope=openid
&response_type=code
&redirect_uri=https://jwt.ms
&state=abc
&nonce=xyz  
&code_challenge=Yzc3NWU3Yjc1N2VkZTYzMGNkMGFhMTExM2JkMTAyNjYxYWIzODgyOWNhNTJhNjQyMmFiNzgyODYyZjI2ODY0Ng==
&code_challenge_method=S256

When redeeming the code for a token I pass the code_verifier (SHA-256 hash) but my IdentityServer logs the following error:

"Transformed code verifier does not match code challenge".

POST https://localhost:5000/connect/token
client_id=pkceclient
grant_type=authorization_code
code:-CesrmjPYjdLdDd5AviOZpR6GdjjkZia_ZapoJdGUZI
redirect_uri=https://jwt.ms
code_verifier=c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646

In his blog post, the author uses the following code to generate the parts.

var verifier = CryptoRandom.CreateRandomKeyString(64);
var challenge = verifier.ToCodeChallenge();

but I cannot find the code in the repositories for the ToCodeChallenge method.

Why doesn't my manually generated challenge match the one used in the verification process, what am I missing?


Solution

  • While putting this question together I came across the specification document for PKCE and found the following line:

    code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

    It turns out the ASCII part is not carried out by the online tools that I used.

    Implementing the steps in code I get the following which, when substituting the values from before, passes the verification in the second step of the process.

    var codeVerifier = "c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646";
    var codeVerifierBytes = Encoding.ASCII.GetBytes(codeVerifier);
    var hashedBytes = codeVerifierBytes.Sha256();
    var transformedCodeVerifier = Base64Url.Encode(hashedBytes);
    

    code_challenge: 51FaJvQFsiNdiFWIq2EMWUKeAqD47dqU_cHzJpfHl-Q

    code_verifier: c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646