Sign In Register

How can we help you today?

Start a new topic

Problem with signing AWS request (Signature Version 4)

Hello,


I'm trying to sign an AWS http request. I have the correct cannonical request and string to sign, but the signature key i'm generating doesn't match the AWS documentation.


The problem is in the HMAC function. The AWS documentation states that: The key derivation requires that you use a binary-formatted digest.


I'm using the following function:

function HMAC (key, data)

{

    return valueHex = Spark.getDigester().hmacSha256Hex(key, data);

}


Which is obviously incorrect because the HMAC function is supposet to return a binary digest.


How can I generate a binary Sha256 hmac with GameSparks?


Link to the documentation https://docs.amazonaws.cn/en_us/general/latest/gr/sigv4-calculate-signature.html



1 Comment

Hi Radu, 


You will need to utilize the jsHash library to generate the appropriate hash. This below code snippet can be placed into a module: 


  

/*
 A JavaScript implementation of the SHA family of hashes, as
 defined in FIPS PUB 180-4 and FIPS PUB 202, as well as the corresponding
 HMAC implementation as defined in FIPS PUB 198a
 Copyright Brian Turek 2008-2017
 Distributed under the BSD License
 See http://caligatio.github.com/jsSHA/ for more information
 Several functions taken from Paul Johnston
*/
'use strict';(function(I){function w(c,a,d){var k=0,b=[],g=0,f,n,h,e,m,q,y,p,l=!1,t=[],r=[],u,z=!1;d=d||{};f=d.encoding||"UTF8";u=d.numRounds||1;if(u!==parseInt(u,10)||1>u)throw Error("numRounds must a integer >= 1");if(0===c.lastIndexOf("SHA-",0))if(q=function(b,a){return A(b,a,c)},y=function(b,a,k,f){var g,e;if("SHA-224"===c||"SHA-256"===c)g=(a+65>>>9<<4)+15,e=16;else throw Error("Unexpected error in SHA-2 implementation");for(;b.length<=g;)b.push(0);b[a>>>5]|=128<<24-a%32;a=a+k;b[g]=a&4294967295;
b[g-1]=a/4294967296|0;k=b.length;for(a=0;a<k;a+=e)f=A(b.slice(a,a+e),f,c);if("SHA-224"===c)b=[f[0],f[1],f[2],f[3],f[4],f[5],f[6]];else if("SHA-256"===c)b=f;else throw Error("Unexpected error in SHA-2 implementation");return b},p=function(b){return b.slice()},"SHA-224"===c)m=512,e=224;else if("SHA-256"===c)m=512,e=256;else throw Error("Chosen SHA variant is not supported");else throw Error("Chosen SHA variant is not supported");h=B(a,f);n=x(c);this.setHMACKey=function(b,a,g){var e;if(!0===l)throw Error("HMAC key already set");
if(!0===z)throw Error("Cannot set HMAC key after calling update");f=(g||{}).encoding||"UTF8";a=B(a,f)(b);b=a.binLen;a=a.value;e=m>>>3;g=e/4-1;if(e<b/8){for(a=y(a,b,0,x(c));a.length<=g;)a.push(0);a[g]&=4294967040}else if(e>b/8){for(;a.length<=g;)a.push(0);a[g]&=4294967040}for(b=0;b<=g;b+=1)t[b]=a[b]^909522486,r[b]=a[b]^1549556828;n=q(t,n);k=m;l=!0};this.update=function(a){var c,f,e,d=0,p=m>>>5;c=h(a,b,g);a=c.binLen;f=c.value;c=a>>>5;for(e=0;e<c;e+=p)d+m<=a&&(n=q(f.slice(e,e+p),n),d+=m);k+=d;b=f.slice(d>>>
5);g=a%m;z=!0};this.getHash=function(a,f){var d,h,m,q;if(!0===l)throw Error("Cannot call getHash after setting HMAC key");m=C(f);switch(a){case "HEX":d=function(a){return D(a,e,m)};break;case "B64":d=function(a){return E(a,e,m)};break;case "BYTES":d=function(a){return F(a,e)};break;case "ARRAYBUFFER":try{h=new ArrayBuffer(0)}catch(v){throw Error("ARRAYBUFFER not supported by this environment");}d=function(a){return G(a,e)};break;default:throw Error("format must be HEX, B64, BYTES, or ARRAYBUFFER");
}q=y(b.slice(),g,k,p(n));for(h=1;h<u;h+=1)q=y(q,e,0,x(c));return d(q)};this.getHMAC=function(a,f){var d,h,t,u;if(!1===l)throw Error("Cannot call getHMAC without first setting HMAC key");t=C(f);switch(a){case "HEX":d=function(a){return D(a,e,t)};break;case "B64":d=function(a){return E(a,e,t)};break;case "BYTES":d=function(a){return F(a,e)};break;case "ARRAYBUFFER":try{d=new ArrayBuffer(0)}catch(v){throw Error("ARRAYBUFFER not supported by this environment");}d=function(a){return G(a,e)};break;default:throw Error("outputFormat must be HEX, B64, BYTES, or ARRAYBUFFER");
}h=y(b.slice(),g,k,p(n));u=q(r,x(c));u=y(h,e,m,u);return d(u)}}function l(){}function D(c,a,d){var k="";a/=8;var b,g;for(b=0;b<a;b+=1)g=c[b>>>2]>>>8*(3+b%4*-1),k+="0123456789abcdef".charAt(g>>>4&15)+"0123456789abcdef".charAt(g&15);return d.outputUpper?k.toUpperCase():k}function E(c,a,d){var k="",b=a/8,g,f,n;for(g=0;g<b;g+=3)for(f=g+1<b?c[g+1>>>2]:0,n=g+2<b?c[g+2>>>2]:0,n=(c[g>>>2]>>>8*(3+g%4*-1)&255)<<16|(f>>>8*(3+(g+1)%4*-1)&255)<<8|n>>>8*(3+(g+2)%4*-1)&255,f=0;4>f;f+=1)8*g+6*f<=a?k+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(n>>>
6*(3-f)&63):k+=d.b64Pad;return k}function F(c,a){var d="",k=a/8,b,g;for(b=0;b<k;b+=1)g=c[b>>>2]>>>8*(3+b%4*-1)&255,d+=String.fromCharCode(g);return d}function G(c,a){var d=a/8,k,b=new ArrayBuffer(d);for(k=0;k<d;k+=1)b[k]=c[k>>>2]>>>8*(3+k%4*-1)&255;return b}function C(c){var a={outputUpper:!1,b64Pad:"=",shakeLen:-1};c=c||{};a.outputUpper=c.outputUpper||!1;!0===c.hasOwnProperty("b64Pad")&&(a.b64Pad=c.b64Pad);if("boolean"!==typeof a.outputUpper)throw Error("Invalid outputUpper formatting option");if("string"!==
typeof a.b64Pad)throw Error("Invalid b64Pad formatting option");return a}function B(c,a){var d;switch(a){case "UTF8":case "UTF16BE":case "UTF16LE":break;default:throw Error("encoding must be UTF8, UTF16BE, or UTF16LE");}switch(c){case "HEX":d=function(a,b,c){var f=a.length,d,h,e,m,q;if(0!==f%2)throw Error("String of HEX type must be in byte increments");b=b||[0];c=c||0;q=c>>>3;for(d=0;d<f;d+=2){h=parseInt(a.substr(d,2),16);if(isNaN(h))throw Error("String of HEX type contains invalid characters");
m=(d>>>1)+q;for(e=m>>>2;b.length<=e;)b.push(0);b[e]|=h<<8*(3+m%4*-1)}return{value:b,binLen:4*f+c}};break;case "TEXT":d=function(c,b,d){var f,n,h=0,e,m,q,l,p,r;b=b||[0];d=d||0;q=d>>>3;if("UTF8"===a)for(r=3,e=0;e<c.length;e+=1)for(f=c.charCodeAt(e),n=[],128>f?n.push(f):2048>f?(n.push(192|f>>>6),n.push(128|f&63)):55296>f||57344<=f?n.push(224|f>>>12,128|f>>>6&63,128|f&63):(e+=1,f=65536+((f&1023)<<10|c.charCodeAt(e)&1023),n.push(240|f>>>18,128|f>>>12&63,128|f>>>6&63,128|f&63)),m=0;m<n.length;m+=1){p=h+
q;for(l=p>>>2;b.length<=l;)b.push(0);b[l]|=n[m]<<8*(r+p%4*-1);h+=1}else if("UTF16BE"===a||"UTF16LE"===a)for(r=2,e=0;e<c.length;e+=1){f=c.charCodeAt(e);"UTF16LE"===a&&(m=f&255,f=m<<8|f>>>8);p=h+q;for(l=p>>>2;b.length<=l;)b.push(0);b[l]|=f<<8*(r+p%4*-1);h+=2}return{value:b,binLen:8*h+d}};break;case "B64":d=function(a,b,c){var f=0,d,h,e,m,q,l,p;if(-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw Error("Invalid character in base-64 string");h=a.indexOf("=");a=a.replace(/\=/g,"");if(-1!==h&&h<a.length)throw Error("Invalid '=' found in base-64 string");
b=b||[0];c=c||0;l=c>>>3;for(h=0;h<a.length;h+=4){q=a.substr(h,4);for(e=m=0;e<q.length;e+=1)d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(q[e]),m|=d<<18-6*e;for(e=0;e<q.length-1;e+=1){p=f+l;for(d=p>>>2;b.length<=d;)b.push(0);b[d]|=(m>>>16-8*e&255)<<8*(3+p%4*-1);f+=1}}return{value:b,binLen:8*f+c}};break;case "BYTES":d=function(a,b,c){var d,n,h,e,m;b=b||[0];c=c||0;h=c>>>3;for(n=0;n<a.length;n+=1)d=a.charCodeAt(n),m=n+h,e=m>>>2,b.length<=e&&b.push(0),b[e]|=d<<8*(3+m%4*-1);
return{value:b,binLen:8*a.length+c}};break;case "ARRAYBUFFER":try{d=new ArrayBuffer(0)}catch(k){throw Error("ARRAYBUFFER not supported by this environment");}d=function(a,b,c){var d,n,h,e;b=b||[0];c=c||0;n=c>>>3;for(d=0;d<a.byteLength;d+=1)e=d+n,h=e>>>2,b.length<=h&&b.push(0),b[h]|=a[d]<<8*(3+e%4*-1);return{value:b,binLen:8*a.byteLength+c}};break;default:throw Error("format must be HEX, TEXT, B64, BYTES, or ARRAYBUFFER");}return d}function r(c,a){return c>>>a|c<<32-a}function J(c,a,d){return c&a^
~c&d}function K(c,a,d){return c&a^c&d^a&d}function L(c){return r(c,2)^r(c,13)^r(c,22)}function M(c){return r(c,6)^r(c,11)^r(c,25)}function N(c){return r(c,7)^r(c,18)^c>>>3}function O(c){return r(c,17)^r(c,19)^c>>>10}function P(c,a){var d=(c&65535)+(a&65535);return((c>>>16)+(a>>>16)+(d>>>16)&65535)<<16|d&65535}function Q(c,a,d,k){var b=(c&65535)+(a&65535)+(d&65535)+(k&65535);return((c>>>16)+(a>>>16)+(d>>>16)+(k>>>16)+(b>>>16)&65535)<<16|b&65535}function R(c,a,d,k,b){var g=(c&65535)+(a&65535)+(d&65535)+
(k&65535)+(b&65535);return((c>>>16)+(a>>>16)+(d>>>16)+(k>>>16)+(b>>>16)+(g>>>16)&65535)<<16|g&65535}function x(c){var a=[],d;if(0===c.lastIndexOf("SHA-",0))switch(a=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428],d=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225],c){case "SHA-224":break;case "SHA-256":a=d;break;case "SHA-384":a=[new l,new l,new l,new l,new l,new l,new l,new l];break;case "SHA-512":a=[new l,new l,new l,
new l,new l,new l,new l,new l];break;default:throw Error("Unknown SHA variant");}else throw Error("No SHA variants supported");return a}function A(c,a,d){var k,b,g,f,n,h,e,m,l,r,p,w,t,x,u,z,A,B,C,D,E,F,v=[],G;if("SHA-224"===d||"SHA-256"===d)r=64,w=1,F=Number,t=P,x=Q,u=R,z=N,A=O,B=L,C=M,E=K,D=J,G=H;else throw Error("Unexpected error in SHA-2 implementation");d=a[0];k=a[1];b=a[2];g=a[3];f=a[4];n=a[5];h=a[6];e=a[7];for(p=0;p<r;p+=1)16>p?(l=p*w,m=c.length<=l?0:c[l],l=c.length<=l+1?0:c[l+1],v[p]=new F(m,
l)):v[p]=x(A(v[p-2]),v[p-7],z(v[p-15]),v[p-16]),m=u(e,C(f),D(f,n,h),G[p],v[p]),l=t(B(d),E(d,k,b)),e=h,h=n,n=f,f=t(g,m),g=b,b=k,k=d,d=t(m,l);a[0]=t(d,a[0]);a[1]=t(k,a[1]);a[2]=t(b,a[2]);a[3]=t(g,a[3]);a[4]=t(f,a[4]);a[5]=t(n,a[5]);a[6]=t(h,a[6]);a[7]=t(e,a[7]);return a}var H;H=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,
1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];"function"===typeof define&&define.amd?
define(function(){return w}):"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(module.exports=w),exports=w):I.jsSHA=w})(this);


Your hashing function will look like so: 

 

function hmac(key, keyEncoding, string) {
    var shaObj = new jsSHA("SHA-256", "TEXT");
    shaObj.setHMACKey( key, keyEncoding );
    shaObj.update( string );
    return shaObj.getHMAC( "HEX" );
}

 

Hope this helps - Patrick.  


Login to post a comment