Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 892
jhhwilliams Avatar asked Nov 04 '19 04:11

jhhwilliams


People also ask

What is code challenge PKCE?

PKCE code verifier and challenge For devices that can perform a SHA256 hash, the code challenge is a BASE64-URL-encoded string of the SHA256 hash of the code verifier.

What is OAuth PKCE?

“PKCE (RFC 7636) is an extension to the Authorization Code flow to prevent several attacks and to be able to securely perform the OAuth exchange from public clients.” The OAuth 2.0 spec is the industry standard protocol for authorization and allows users to grant permission for apps to access their Dropbox data.

How do you create a code challenge?

Create code challenge: Generate a code_challenge from the code_verifier that will be sent to Auth0 to request an authorization_code . Authorize user: Request the user's authorization and redirect back to your app with an authorization_code . Request tokens: Exchange your authorization_code and code_verifier for tokens.


2 Answers

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

like image 54
jhhwilliams Avatar answered Oct 12 '22 20:10

jhhwilliams


Following links helps to achieve the PKCE-AuthZ-Code flow.

https://auth0.com/docs/api-auth/tutorials/authorization-code-grant-pkce

https://github.com/gilbert-fernandes/S256Code/blob/master/src/S256Code.java

like image 42
Zeigeist Avatar answered Oct 12 '22 21:10

Zeigeist