Created
January 26, 2016 23:18
-
-
Save DinoChiesa/75796b27828cf8e15c91 to your computer and use it in GitHub Desktop.
pre-request script for Postman, to perform HttpSignature calculation. Also SHA-256 message digest.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function computeHttpSignature(config, headerHash) { | |
var template = 'keyId="${keyId}",algorithm="${algorithm}",headers="${headers}",signature="${signature}"', | |
sig = template; | |
// compute sig here | |
var signingBase = ''; | |
config.headers.forEach(function(h){ | |
if (signingBase !== '') { signingBase += '\n'; } | |
signingBase += h.toLowerCase() + ": " + headerHash[h]; | |
}); | |
var hashf = (function() { | |
switch (config.algorithm) { | |
case 'hmac-sha1': return CryptoJS.HmacSHA1; | |
case 'hmac-sha256': return CryptoJS.HmacSHA256; | |
case 'hmac-sha512': return CryptoJS.HmacSHA512; | |
default : return null; | |
} | |
}()); | |
var hash = hashf(signingBase, config.secretkey); | |
var signatureOptions = { | |
keyId : config.keyId, | |
algorithm: config.algorithm, | |
headers: config.headers, | |
signature : CryptoJS.enc.Base64.stringify(hash) | |
}; | |
// build sig string here | |
Object.keys(signatureOptions).forEach(function(key) { | |
var pattern = "${" + key + "}", | |
value = (typeof signatureOptions[key] != 'string') ? signatureOptions[key].join(' ') : signatureOptions[key]; | |
sig = sig.replace(pattern, value); | |
}); | |
return sig; | |
} | |
var curDate = new Date().toGMTString(); | |
var targetUrl = request.url.trim(); // there may be surrounding ws | |
targetUrl = targetUrl.replace(new RegExp('^https?://[^/]+/'),'/'); // strip hostname | |
var method = request.method.toLowerCase(); | |
var sha256digest = CryptoJS.SHA256(request.data); | |
var base64sha256 = CryptoJS.enc.Base64.stringify(sha256digest); | |
var computedDigest = 'sha-256=' + base64sha256; | |
var headerHash = { | |
date : curDate, | |
digest : computedDigest, | |
'(request-target)' : method + ' ' + targetUrl | |
}; | |
var config = { | |
algorithm : 'hmac-sha256', | |
keyId : environment['key-id'], | |
secretkey : environment['shared-secret'], | |
headers : [ '(request-target)', 'date', 'digest' ] | |
}; | |
var sig = computeHttpSignature(config, headerHash); | |
postman.setEnvironmentVariable('httpsig', sig); | |
postman.setEnvironmentVariable('computed-digest', computedDigest); | |
postman.setEnvironmentVariable("current-date", curDate); | |
postman.setEnvironmentVariable("target-url", targetUrl); |
Good, thanks ๐
Thanks for the head start on this; I was able to adapt to our use.
Some suggestions:
- Base64 decode the
secretKey
before use - change
headerHash
to also pull from the request:
var headerHash = Object.assign(Object.assign({},pm.request.headers.toObject(true)), {
date : curDate,
digest : computedDigest,
'(request-target)' : method + ' ' + targetUrl
});
- Parameterize or at least call out the hash algorithm name might need adjusting (it did in my case)
Trying to get this to work...getting:
"TypeError: Cannot read property 'sigBytes' of undefined"
In the postman GUI. Any ideas where to start? What variables should be defined to start with? I have defined:
keyId
shared-secret
with values in the environment settings.
I think it's because you need to add variables to the environment with a different syntax
notice pm.environment.get("signature_key_id")
and pm.environment.get("signature_key")
var config = {
algorithm : 'hmac-sha256',
keyId : pm.environment.get("signature_key_id"),
secretkey : pm.environment.get("signature_key"),
headers : [ '(request-target)', 'digest', 'date']
};
Thanks for the head start on this; I was able to adapt to our use.
Some suggestions:
* Base64 decode the `secretKey` before use * change `headerHash` to also pull from the request:
var headerHash = Object.assign(Object.assign({},pm.request.headers.toObject(true)), { date : curDate, digest : computedDigest, '(request-target)' : method + ' ' + targetUrl });
* Parameterize or at least call out the hash algorithm name might need adjusting (it did in my case)
Specifically you need to Base64 decode with
CryptoJS.enc.Base64.parse('your-secret-key')
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
๐ Very handy. Nice work.