PKCE allows us to secure the final leg of the authentication process. Before PKCE, we had a way to secure the phone network service to an authorization server by using an identity service like PingOne for Customers, but not the communication between the native mobile app and the phone network service, which all happens local to the device.
While PKCE doesn’t stop malicious apps from listening in on network services communicating the authorization code, it does make that information incomplete. PKCE adds another required piece to the puzzle that only the good app and authorization server know, so that the authorization server gives the access token only when an authorization code is accompanied by the additional “secret” created by the good native app.
PKCE secures the OAuth 2.0 authorization code flow by introducing this secret into the authorization process. It’s similar to using a passphrase that you say to get special access to that exclusive restaurant, club or speak-easy (in case you have stumbled upon a time machine to take you back to the 1920’s.) The “secret” is generated by the good app and is a dynamically created, cryptographically random key, which verifies the code was obtained legitimately.
Here’s how it works. In the initial request, instead of simply asking for authorization, the request contains three things:
The authorization request
A code challenge (or, equivalently, the transformed code_verifier, t(code_verifier)) that was created BEFORE the request is sent
A transformation method (the t() function)
Then, when the client gets back the message, instead of simply sending the authorization code to the token endpoint, the client sends the request for an access token and includes the authorization code and the code_verifier. The token endpoint transforms code_verifier using the transformation method received earlier and compares it to the code challenge, which was also sent earlier. It authenticates if and only if the codes match.
Since the malicious app doesn’t have the code_verifier, it can’t obtain the access token—and therefore the resource is protected. The authorization server will deny requests for an access token without the correct secret.
In other situations, like SPAs or browser apps, there’ll likely be a better or easier solution than what PKCE provides. But for native apps using the authorization code grant type, what I like to call a little “PKCE dust” offers strong security. Come try it out with a free trial of PingOne for Customers.