function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Ian RatcliffeIan Ratcliffe 

Generating OAuth Code Challenge and Code Verifier in PHP

I've successfully gone through the process for Web Server OAuth Authentication Flow outlined below to aquire an access and request token:

https://developer.salesforce.com/docs/atlas.en-us.200.0.api_rest.meta/api_rest/intro_understanding_web_server_oauth_flow.htm

However I'm having difficulty adding in the optional additional security measure of adding a code_challenge and code_verifier in the requests.

I have tried...
$random = openssl_random_pseudo_bytes(128);
$verifier = base64_encode($random);
$challenge = base64_encode(hash('sha256', $verifier));
Or maybe don't encode the verifier before applying the hash
$random = openssl_random_pseudo_bytes(128);
$verifier = base64_encode($random);
$challenge = base64_encode(hash('sha256', $random));
Or maybe they want 128 chars instead of bytes
$random = bin2hex(openssl_random_pseudo_bytes(64));
Or maybe the encoding needs to be url safe:
function base64url_encode($data) {
  return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

No luck so far. Has anyone manged to do the sucecssfuly in PHP or otherwise, or could spot a glaring mistake I'm making, who could offer some advice? 


 
Best Answer chosen by Ian Ratcliffe
Ian RatcliffeIan Ratcliffe
    function base64url_encode($plainText)
    {
        $base64 = base64_encode($plainText);
        $base64 = trim($base64, "=");
        $base64url = strtr($base64, '+/', '-_');
        return ($base64url);
    }

    $random = bin2hex(openssl_random_pseudo_bytes(32));
    $verifier = base64url_encode(pack('H*', $random));
    $challenge = base64url_encode(pack('H*', hash('sha256', $verifier)));

Got there is the end, hope this helps someone!

All Answers

Ian RatcliffeIan Ratcliffe
https://tools.ietf.org/html/rfc7636#page-17

I've tried the process with the example from above where
 
$verifier = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk";
$challenge = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM";

and this works. So I have an expected value for a test for my method. I'll post the function when I crack it, unless someone beats me to it.
Ian RatcliffeIan Ratcliffe
    function base64url_encode($plainText)
    {
        $base64 = base64_encode($plainText);
        $base64 = trim($base64, "=");
        $base64url = strtr($base64, '+/', '-_');
        return ($base64url);
    }

    $random = bin2hex(openssl_random_pseudo_bytes(32));
    $verifier = base64url_encode(pack('H*', $random));
    $challenge = base64url_encode(pack('H*', hash('sha256', $verifier)));

Got there is the end, hope this helps someone!
This was selected as the best answer
TonyScottTonyScott
Thanks Ian, this has been driving me up the wall. The key was using bin2hex and pack. You can actually specify the full 128 bytes in the openssl_random_pseudo_bytes call. Cheers, Tony