Search code examples
phpapioauthpostmansignature

OAuth 1.0 Generate Signature Difference in POSTMAN and PHP code



Im want to authenticate to an API that uses OAuth as auth method.
I already created this code to generate a signature.
**THESE ARE ALL DUMMY DATA FOR TEST PURPOSES!**
$consumerKey     = "468gu89fu8934uf3jf935jg5i2954";
$consumerSecret  = "9385u3jg389gj349856u985j349t8";
$tokenSecret     = "353459385j3fojlkvm34tfewoijr4";
$accessToken     = "598u45983jf3jr3i45jkr3elkrj34";
$realm           = "389534j5oi";
$signatureMethod = "HMAC-SHA256";
$version         = "1.0";

function generateSignature($request, $timestamp, $nonce)
{
    Global $consumerKey, $accessToken, $consumerSecret, $tokenSecret, $realm, $signatureMethod, $version;
    $base = $request['method'] . "&" . rawurlencode($request['url']) . "&"
    . rawurlencode("oauth_consumer_key=" . rawurlencode($consumerKey)
    . "&oauth_nonce=" . rawurlencode($nonce)
    . "&oauth_signature_method=" . rawurlencode($signatureMethod)
    . "&oauth_timestamp=" . rawurlencode($timestamp)
    . "&oauth_token=" . rawurlencode($accessToken)
    . "&oauth_version=" . rawurlencode($version));

    $key = rawurlencode($consumerSecret) . '&' . rawurlencode($tokenSecret);
    $signature = base64_encode(hash_hmac('sha256', $base, $key));
    return $signature;

}

This function generates a correct signature that matches the signature I generate with this online tool: https://www.devglan.com/online-tools/hmac-sha256-online

However when I add all these parameters to POSTMAN, It generates a different signature.
It doesn't match at all with the signature I generate.
The problem I have is that the API endpoint get authenticated successfully with POSTMAN but not with my own generated signatures.
Lets take these credentials to generate a signature.

$consumerKey     = "468gu89fu8934uf3jf935jg5i2954";
$consumerSecret  = "9385u3jg389gj349856u985j349t8";
$tokenSecret     = "353459385j3fojlkvm34tfewoijr4";
$accessToken     = "598u45983jf3jr3i45jkr3elkrj34";
$realm           = "389534j5oi";
$signatureMethod = "HMAC-SHA256";
$version         = "1.0";
$nonce           = "LQgbebz9DTe";
$timestamp       = "1636124296";
$url             = "https://fakeapi.com/auth";
$method          = "GET";

These are the signatures that get generated:

My application: NWNjMzgyOGJiYWU1YmNiNzNlMzRjMjA5ZGNiNmIzZWNiNTAzYjRhNjE0NTMyZjYyN2MwNzM5ZjNmZDEzNDYxNg==
POSTMAN: XMOCi7rlvLc%2BNMIJ3Laz7LUDtKYUUy9ifAc58%2F0TRhY%3D

As you can see there are 2 completely different signatures generated while in both applications I use the same credentials, you can test this as well.
Now comes my question:
Can anyone tell me why these signatures are different and what do I need to do to let my own signature work as well? Because the one that postman generates works perfectly.
Im really stuck and my colleagues also can't find out why.
Any help is appreciated :)


Solution

  • The problem here can be found in the encoding of the base signature to generate the actual signature. You will need to set the binary flag in the hash_hmac method to true. This will return the raw binary representation of the message digest, which in turn needs to be base64 encoded.

    $signature = base64_encode(hash_hmac('sha256', $base, $key, true));
    

    https://www.php.net/manual/en/function.hash-hmac.php

    This will produce a signature equal to what Postman is doing.