问题
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
回答1:
How about this modification?
Reason of issue:
Both value
and key
of Utilities.computeHmacSha256Signature(value, key)
are "String" or "Byte[]". In your script, when var kDate = hash( dateStamp, kSecret );
is run, kDate
is the byte array. But when var kRegion = hash( regionName, kDate );
is run, regionName
and kDate
are "String" and "Byte[]", respectively. By this, after var kRegion = hash( regionName, kDate );
, the result is not the same with that of jsSHA.
Modification points:
- In order to avoid this, for example, please convert "String" to "Byte[]".
Modified script:
function sample() {
var key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY';
var dateStamp = '20150830';
var regionName = 'us-east-1';
var serviceName = 'iam';
var kSecret = 'AWS4' + key;
regionName = Utilities.newBlob(regionName).getBytes(); // Added
serviceName = Utilities.newBlob(serviceName).getBytes(); // Added
var value = Utilities.newBlob('aws4_request').getBytes(); // Added
var kDate = hash( dateStamp, kSecret );
var kRegion = hash( regionName, kDate );
var kService = hash( serviceName, kRegion );
var kSigning = hash( value, kService );
return kSigning;
}
function hash( payload, key ) {
return Utilities.computeHmacSha256Signature(payload, key);
// return Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, payload, key) // You can also use this.
}
Result:
kDate: 0138c7a6cbd60aa727b2f653a522567439dfb9f3e72b21f9b25941a42f04a7cd
kRegion: f33d5808504bf34812e5fade63308b424b244c59189be2a591dd2282c7cb563f
kService: 199e1f48c602a5ae77ce26a46906920e76fc8427aeaa53da643646fcda1ccfb0
kSigning: c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9
References:
- computeHmacSha256Signature(value, key)
- computeHmacSignature(algorithm, value, key)
- newBlob(data)
- getBytes()
If this was not what you want, I'm sorry.
来源:https://stackoverflow.com/questions/52795984/passing-hashed-data-as-key-to-hash-again-returns-incorrect-results