in reply to Re: HMAC Sha256 Help! (updated)
in thread HMAC Sha256 Help!

thanks for the reply. Well I don' really know what the expected output should be either, thats my issue really.

I tried with the pack function to get the hex key into bytes but with no success either.

as for using hmac_sha256_hex, thanks for the information. I have now changed to hmac_sha256 instead, still no joy but I think thats now the correct hashing mechanism

I really appreciate the assistance thanks.

the full instructions to build the authorization header are:

For GET endpoint:

1. Build a string based on the request METHOD (GET) DATE/TIME APPLICATION ID PATH (API endpoint, e.g. /xxxxxxxxx/api/v1/users/<userID>/factors)

2. Create an HMAC SHA256 hash of step 1 using the Application Key This step is executed by calling the HMAC and producing the hash value

3. Encode the HMAC SHA256 hash from step 2 in Base64

4. Concatenate the "Application ID", ":", and the "Base64 encoded HMAC SHA256 hash" from step 3 ApplicationID:Base64EncodedHMACSHA256Hash

5. Encode the value from step 4 in Base64

6. Concatenate "Basic " and the "Value of Step 5"

the encoding is all ok, its the creation of the HMAC that seems to be my issue.

currently I have it as

#lets check the time $datestring = strftime "%a, %e %b %Y %H:%M:%S GMT", gmtime; #set the strings $method="GET"; $appid="d6468df6c1e8419fb5ec50f62be9a28b"; $appkey="15c7a6e1a5bd73500db29dffd0e19b6c6228b044c64348a6f5d6d470c54fc +208"; $path="/xxxxxxxxxxxx/xxxxxxx/api/v1/users/xxxxx/factors"; #build the hash string $step1="$method\\n$datestring\\n$appid\\n$path"; #hmac sha256hash the string $step2a= encode_base64(hmac_sha256($step1, pack("H*",$appkey))); $step4="$appid:$step2a"; #encode value from step 4 into base 64 $step5 = encode_base64($step4); #now add Basic and the value from step 5 $step6 = ("Basic $step5");

Replies are listed 'Best First'.
Re^3: HMAC Sha256 Help! (updated)
by haukex (Archbishop) on Jul 18, 2017 at 16:42 UTC
    Well I don' really know what the expected output should be either, thats my issue really.

    This does seem to be the central issue. Is there really no example transaction provided in the API documentation? Perhaps you could ask whomever published the API for one? Is there a reference implementation that you could look at? Even if it's in another programming language, you might be able to just read that, or, you could execute it and run a trace (Wireshark) of a successful request?

      unfortunately the documentation is lacking

      I have the following example using go

      // makeHmac: // non-exportable helper to do SHA256 HMAC func makeHmac(data string, key string) string { byteKey, _ := hex.DecodeString(key) byteData := []byte(data) sig := hmac.New(sha256.New, byteKey) sig.Write([]byte(byteData)) return base64.StdEncoding.EncodeToString(sig.Sum(nil)) }

      still none the wiser though!

      I do know that the app key provided should be treated as 32 2 byte values and not 64 1 byte values

      Its this handling of the 32 2 byte values I am unsure of

      thanks again for responding, its driving me slightly mad

        In case this helps, I ran the Go code

        package main import ( "fmt" "encoding/hex" "encoding/base64" "crypto/hmac" "crypto/sha256" ) func main() { x := makeHmac("abcdef","1234567890") fmt.Printf("%s\n", x) } func makeHmac(data string, key string) string { byteKey, _ := hex.DecodeString(key) byteData := []byte(data) sig := hmac.New(sha256.New, byteKey) sig.Write([]byte(byteData)) return base64.StdEncoding.EncodeToString(sig.Sum(nil)) }

        and the result was

        1CBMzMydzanzzzHwnZKJEswN1jqvKZiI3fwBw81t1f4=

        Running this perl

        #!perl use strict; use Digest::SHA qw( hmac_sha256_base64 ); my $digest = hmac_sha256_base64("abcdef", pack "H*",'1234567890'); print $digest;

        gave the same but without the padding

        1CBMzMydzanzzzHwnZKJEswN1jqvKZiI3fwBw81t1f4
        poj

        1. updated with perl code
        
        2. updated with full example code below both giving same result
        GET\n08 Apr 2015 21:37:33 GMT\nd6468df6c1e8419fb5ec50f62be9a28b\n/xxxxxxxxxxxx/xxxxxxx/api/v1/users/xxxxx/factors
        ApplicationID:2LIG2VOfl6swsD6rwRxBHW64dF6WK0vOO+b+VO/UbTk=
        Basic :QXBwbGljYXRpb25JRDoyTElHMlZPZmw2c3dzRDZyd1J4QkhXNjRkRjZXSzB2T08rYitWTy9VYlRrPQ==
        
        
        #!perl use strict; use Digest::SHA qw( hmac_sha256_base64 ); use MIME::Base64; my $datestring = '08 Apr 2015 21:37:33 GMT'; my $method = 'GET'; my $appid = 'd6468df6c1e8419fb5ec50f62be9a28b'; my $appkey = '15c7a6e1a5bd73500db29dffd0e19b6c6228b044c64348a6f5d6d470 +c54fc208'; my $path = '/xxxxxxxxxxxx/xxxxxxx/api/v1/users/xxxxx/factors'; # build the hash string my $step1 = "$method\\n$datestring\\n$appid\\n$path"; print "$step1\n"; # hmac, base64 and add padding my $step3 = hmac_sha256_base64($step1, pack "H*",$appkey); while (length($step3) % 4) { $step3 .= '='; } my $step4 = 'ApplicationID:'.$step3; print "$step4\n"; my $step6 = "Basic :".encode_base64($step4,''); print "$step6\n";
        // GO code package main import ( "fmt" "encoding/hex" "encoding/base64" "crypto/hmac" "crypto/sha256" ) func main() { datestring := "08 Apr 2015 21:37:33 GMT" appid := "d6468df6c1e8419fb5ec50f62be9a28b" appkey:= "15c7a6e1a5bd73500db29dffd0e19b6c6228b044c64348a6f5d6d470c5 +4fc208" path := "/xxxxxxxxxxxx/xxxxxxx/api/v1/users/xxxxx/factors" step1 := "GET\\n"+datestring+"\\n"+appid+"\\n"+path fmt.Printf("%s\n",step1) step4 := "ApplicationID:" + makeHmac( step1, appkey ) fmt.Printf("%s\n",step4) step6 := "Basic :" + base64.StdEncoding.EncodeToString([]byte(step4) +) fmt.Printf("%s\n", step6) } func makeHmac(data string, key string) string { byteKey, _ := hex.DecodeString(key) byteData := []byte(data) sig := hmac.New(sha256.New, byteKey) sig.Write([]byte(byteData)) return base64.StdEncoding.EncodeToString(sig.Sum(nil)) }