cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar
pauldeen
Level VI

How do I generate HMAC-SHA256 hashes in JSL

For querrying a REST API I need to authenticate with HMAC-SHA256. Does anybody know of a way to do this in JSL? We might even use another REST API or webscraper to do it. For example this website: https://www.devglan.com/online-tools/hmac-sha256-online can calculate the hash but how do I make it work?

1 ACCEPTED SOLUTION

Accepted Solutions
Craige_Hales
Super User

Re: How do I generate HMAC-SHA256 hashes in JSL

certutil on windows. openssl on mac. (But I think you might not need to, see final sentence below.)

 

A long time ago in 7 things to know about Twitter  I needed a SHA1. "certutil" is already installed on windows and will apparently do SHA256 as well. You might start with the code in the .zip AUTH.jsl file which uses runprogram and parses the output.

 

You'll get a bunch of choices of varying quality with this search https://www.google.com/search?q=windows+hmac+sha256+certutil

 

The HMAC part is described https://en.wikipedia.org/wiki/HMAC and there appears to be a related function in the AUTH.jsl file. It's been a long time since I thought about it. edit: I probably used the Wikipedia example when the JSL was written. Wikipedia also provides some test cases if you write your own.

 

I think this may be built in to JMP's httpRequest/oauth2 functions as well @Paul_Nelson  @bryan_boone  but I've not studied them yet.

 

Craige

View solution in original post

6 REPLIES 6
Craige_Hales
Super User

Re: How do I generate HMAC-SHA256 hashes in JSL

certutil on windows. openssl on mac. (But I think you might not need to, see final sentence below.)

 

A long time ago in 7 things to know about Twitter  I needed a SHA1. "certutil" is already installed on windows and will apparently do SHA256 as well. You might start with the code in the .zip AUTH.jsl file which uses runprogram and parses the output.

 

You'll get a bunch of choices of varying quality with this search https://www.google.com/search?q=windows+hmac+sha256+certutil

 

The HMAC part is described https://en.wikipedia.org/wiki/HMAC and there appears to be a related function in the AUTH.jsl file. It's been a long time since I thought about it. edit: I probably used the Wikipedia example when the JSL was written. Wikipedia also provides some test cases if you write your own.

 

I think this may be built in to JMP's httpRequest/oauth2 functions as well @Paul_Nelson  @bryan_boone  but I've not studied them yet.

 

Craige
pauldeen
Level VI

Re: How do I generate HMAC-SHA256 hashes in JSL

Definetly interested in the built in solution but in the meantime your solution also works! I replaced SHA1 with SHA256 in line 9 of your auth.jsl file, thanks!

pauldeen
Level VI

Re: How do I generate HMAC-SHA256 hashes in JSL

@Craige_Hales for some reason I got it to work earlier today, then saved it and now it won't work anymore. Can you see my mistake? BITS.jsl and AUTH.jsl from your twitterpackage are also attached for reference.

Update, it was the blocksize, it is 64 for SHA265 I had assumed that is should be 265

 

 

include("BITS.jsl");
SHA256 = Function( {txt},
	{hash, rc, hexdata,temppath},
	try(deleteFile("$temp/deleteme.txt"));
	temppath = Save Text File( "$temp/deleteme.txt", txt );
	If( Host is( "windows" ),
		hash = RunProgram( executable( "certutil" ), options( "-hashfile "|| temppath|| " SHA256" ), readfunction( "text" ) ); // win jmp 11
		//hash = RunProgram( executable( "certutil" ), options( {"-hashfile", temppath, "SHA1"} ), readfunction( "text" ) );
		rc = Pat Match(
			hash,
			Pat Regex( "\[^.+?:\s+]\" ) + Pat Span( "0123456789abcdefABCDEF " ) >> hexdata + Pat Regex(
				"\[\s*CertUtil: -hashfile command completed successfully.\s*$]\"
			)
		);
		If( rc != 1,
			Throw( "bad hash:" || hash )
		);
		hexdata = Regex( hexdata, " ", "", GLOBALREPLACE );
	, // else MAC
		hash = RunProgram( executable( "/usr/bin/openssl" ), options( {"dgst", "-sha1", temppath} ), readfunction( "text" ) );
		hexdata =regex(hash,"=\s*([0-9a-fA-F]{40})\s*","\1");
		if( length(hexdata) != 40, throw("bad hash:" || hash));
	);
	try(deleteFile("$temp/deleteme.txt"),show("did not delete temp file??"));
	Return( Hex To Blob( hexdata ) );
);

HMACSHA256 = Function( {key, message},
    {blocksize = 64}, // Where blocksize is that of the underlying hash function
    //show(length(key));
    If(
        Length( key ) > blocksize, // keys longer than blocksize are shortened
            //print("shorten:");
            key = SHA256( key );
            //show(key,length(key));
    );
    if(
        Length( key ) < blocksize, // keys shorter than blocksize are zero-padded
            key = key || Matrix To Blob( J( (blocksize - Length( key )), 1, 0 ), "uint", 1, "big" )
    );
   //show(length(key));
    o_key_pad = BITS:XORBLOB( Matrix To Blob( J( blocksize, 1, Hex To Number( "5c" ) ), "uint", 1, "big" ), key );
    i_key_pad = BITS:XORBLOB( Matrix To Blob( J( blocksize, 1, Hex To Number( "36" ) ), "uint", 1, "big" ), key );
   
    Return( SHA256( o_key_pad || SHA256( i_key_pad || message ) ) );
);

//from https://www.devglan.com/online-tools/hmac-sha256-online
if("090a613de1a32c513f5477019dbd395fe4c6727708e945277d6af6c5cf7a6778" != hex(HMACSHA256( Char To Blob( "dbc62ec300b2624c580611858d94f2332ac63" ), Char To Blob( "Why don't we test this" ) )), throw("hmac busted"));

I checked the certutil SHA256 function and that generates correct hashes. It seems that the HMACSHA256 or in the BITS functions that it calls, where it goes wrong.

 

Craige_Hales
Super User

Re: How do I generate HMAC-SHA256 hashes in JSL

try uppercase() on the left-hand-side test value. Looks like it works.

Craige

Re: How do I generate HMAC-SHA256 hashes in JSL

HMAC-SHA256 is not currently built in to HTTP Request/OAuth2.

It would have to be done the way Craige described.

pauldeen
Level VI

Re: How do I generate HMAC-SHA256 hashes in JSL

Thanks for confirming that