I'm creating a script that will access AWS services using GAS. I'm using the hashing functions in the Utilities library for all the hashing that is required to create a v4 signature. These functions appear to be able to successfully hash data once, but trying to pass in hashed data into an argument yields incorrect results. Anyone else run into this issue and figure it out?
I know there is something weird going on with Utilities.computeHmacSha256Signature( input, key ), because the arguments can only be byte arrays or strings, and I am passing in combinations of the two. However, when I try to convert the arguments to just byte arrays or strings, I still have no luck.
My key generating code design reference: link
function getSignatureKey( key, dateStamp, regionName, serviceName ) {
var kSecret = 'AWS4' + key;
var kDate = hash( dateStamp, kSecret );
var kRegion = hash( regionName, kDate );
var kService = hash( serviceName, kRegion );
var kSigning = hash( 'aws4_request', kService );
return kSigning;
}
'My' hashing function:
function hash( payload, key ) {
const utf8 = Utilities.Charset.UTF_8;
const sha256 = Utilities.DigestAlgorithm.SHA_256;
if ( !payload ) payload = '';
if ( key ) {
payload = Utilities.computeHmacSha256Signature( payload, key, utf8 );
}
else
payload = Utilities.computeDigest( sha256, payload, utf8 );
return payload;
}
Sample inputs
var key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY';
var date = '20150830';
var region = 'us-east-1';
var service = 'iam';
Key generated from sample inputs from link
c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9
Step by step results Generated by jsSHA
// kDate = HMAC( date, 'AWS4' + key )
0138c7a6cbd60aa727b2f653a522567439dfb9f3e72b21f9b25941a42f04a7cd
// kRegion = HMAC( region, kDate )
f33d5808504bf34812e5fade63308b424b244c59189be2a591dd2282c7cb563f
// kService = HMAC( service, kRegion )
199e1f48c602a5ae77ce26a46906920e76fc8427aeaa53da643646fcda1ccfb0
// kSigning = HMAC( 'aws4_request', kService ) -- matches example
c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9
My results Running the results of hash() function above(through hex encoder)
// var kSecret = 'AWS4' + key;
// var kDate = hash( dateStamp, kSecret )
0138c7a6cbd60aa727b2f653a522567439dfb9f3e72b21f9b25941a42f04a7cd
// var kRegion = hash( regionName, kDate );
67a1e58cdd80d4ae0eab4345f1cac6e4faab10efb9c21fd7b30e5e9118462c79
// var kService = hash( serviceName, kRegion );
295384288c76cdb665c1cbf8281250b93b6ae257b98b72e4be0876a9e8a0b409
// var kSigning = hash( 'aws4_request', kService );
bfb393756c5518b668b5055910bb715e4a879c0e10bb22d3140b1e82b2a50a2c
How about this modification?
Reason of issue:
Both
value
andkey
ofUtilities.computeHmacSha256Signature(value, key)
are "String" or "Byte[]". In your script, whenvar kDate = hash( dateStamp, kSecret );
is run,kDate
is the byte array. But whenvar kRegion = hash( regionName, kDate );
is run,regionName
andkDate
are "String" and "Byte[]", respectively. By this, aftervar kRegion = hash( regionName, kDate );
, the result is not the same with that of jsSHA.Modification points:
Modified script:
Result:
References:
If this was not what you want, I'm sorry.