Discussion Forums



Thread: signature authentication with JavaScript?

This question is not answered. Helpful answers available: 2. Correct answers available: 1.

Welcome, Guest Help
Login Login


Permlink Replies: 37 - Pages: 3 [ 1 2 3 | Next ] - Last Post: Jul 27, 2009 3:46 AM by: Brandon Checketts
Aaron Shepard
RealName(TM)


Posts: 71
Registered: 2/8/06
signature authentication with JavaScript?
Posted: May 8, 2009 9:21 PM PDT
 
  Click to reply to this thread Reply

My application uses just HTML forms, JavaScript, and XSLT. That's it. Is there any way to produce signatures for authentication with this combination? Or has Amazon just destroyed my app, developed over years and used by over 5,000 visitors a week?

Aaron



Jim L Taylor

Posts: 2,578
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 8, 2009 9:30 PM PDT   in response to: Aaron Shepard
 
  Click to reply to this thread Reply

Maybe this will help.  I'm not a PHP or JS expert but sounded like it might a be a start since some have posted PHP solutions.

http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_base64_encode/


Jim


Andy Earnshaw

Posts: 11
Registered: 4/17/07
Re: signature authentication with JavaScript?
Posted: May 10, 2009 7:33 AM PDT   in response to: Jim L Taylor
 
  Click to reply to this thread Reply

I'm in the same boat, I have javascript widgets that use the Product Advertising API.  However, building the signature with Javascript isn't something I'm planning on doing.  To quote the documentation:

IMPORTANT: Your Secret Access Key is a secret, and should be known only by you and AWS. You should never include your Secret Access Key in your requests to AWS. You should never e-mail your Secret Access Key to anyone. It is important to keep your Secret Access Key confidential to protect your account.


Since JS code is open to anyone for viewing, it's impossible to keep the key hidden from prying eyes.  Therefore, it will be necessary to route ALL calls through a web server instead.

I know, "ouch!".

Andy

C. Sowa

Posts: 194
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 10, 2009 1:20 PM PDT   in response to: Aaron Shepard
 
  Click to reply to this thread Reply

Assuming the use of an already working REST query (generally the case with a retro-fit), I came up with the following:


function fnSignedQuery( strQuery, strKey ) {
    strQuery += "&Timestamp=" + timestamp();
    var strSignedQuery;
    var strToSign = strQuery.replace( /(https?:\/\/)([^\/]*)(\/.*)\?(.*)/i,
        function( strMatch, strScheme, strHost, strUri, strParams ) {
            var aParams = strParams.split("&").sort();
            for ( var i in aParams ) {
                var aKV = aParams[i].split("=");
                for ( var j in aKV )
                    aKV[j] = encodeURIComponentAWS( aKV[j] );
                aParams[i] = aKV.join("=");
            }
            strParams = aParams.join("&");
            strHost = strHost.toLowerCase();
            strSignedQuery = strScheme + strHost + strUri + "?" + strParams;
            return (new Array( "GET", strHost, strUri, strParams )).join("\n");
        })
    strSignature = encodeURIComponentAWS( Base64.encode( HMAC_SHA256_MAC( strKey, strToSign ) ) );
    strSignedQuery += "&Signature=" + strSignature;
    return strSignedQuery;
}
 
function encodeURIComponentAWS( str ) {
    // developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Functions/EncodeURIComponent
    // "... encodeURIComponent escapes all characters except the following: alphabetic, decimal digits, - _ . ! ~ * ' ( )  ..."
    // same for MS JScript ?  seems to be.
    return fnTranslate( encodeURIComponent( str ),
        [ ["!", "%21"], ["'", "%27"], ["(", "%28"], [")", "%29"], ["*", "%2A"] ] );
}
 
function fnTranslate( str, aTranslate ) {
    for ( var i in aTranslate )
        str = str.replace( aTranslate[i][0], aTranslate[i][1] );
    return str;
}
 
function timestamp() { return toZString( new Date() ) }
 
function toZString( dt ) {
    // "Sun, 10 May 2009 18:45:50 UTC" to "2009-05-10T18:45:50Z":
    return dt.toUTCString().replace( /.{3}, (\d{2}) .{3} (\d{4}) (\d{2}:\d{2}:\d{2}) UTC/,
        function(strMatch, strDay, strYear, strTime) {
            strMonth = (dt.getUTCMonth()+1).toString().replace( /^(\d)$/, "0$1" );
            return strYear + "-" + strMonth + "-" + strDay + "T" + strTime + "Z";
        });
}


This uses http://point-at-infinity.org/jssha256/ for the HMAC SHA256 and http://www.webtoolkit.info/ for the Base64.


BUT - the signature isn't accepted by Amazon.  Not sure why, all the intermediate steps check out as far as I can tell.  Maybe an extra set of eyes can spot something, then we all can benefit.


Thanks !



Aaron Shepard
RealName(TM)


Posts: 71
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 10, 2009 4:24 PM PDT   in response to: C. Sowa
 
  Click to reply to this thread Reply

FractalNavel, I'm too much of a novice at JavaScript to be able to follow most of this, but I noticed you're trying to construct your own timestamp. Isn't there a timestamp function in JavaScript that returns a complete one automatically?

Aaron



Jim L Taylor

Posts: 2,578
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 10, 2009 4:58 PM PDT   in response to: C. Sowa
 
  Click to reply to this thread Reply

I assume you've double checked the result of the sort?  Maybe post the strToSign value prior to its submission for hashing.  That might help one of us see the problem.

Jim


C. Sowa

Posts: 194
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 10, 2009 5:09 PM PDT   in response to: Aaron Shepard
 
  Click to reply to this thread Reply


aaronshepard wrote:
... Isn't there a timestamp function in JavaScript that returns a complete one automatically?

Not the way you're thinking of, no.  The AWS "Timestamp" parameter just contains a particular string representation of a datetime (  http://en.wikipedia.org/wiki/ISO_8601 ).  JavaScript doesn't associate any special meaning with this.  It also does not have a native "toString" implementation for this format, nor provides the ability to specify an arbitrary format string like many (most?) other languages.

I've rolled-my-own script for this in different ways over the years.  I'm sure there are libraries & one-off functions out there that handle this in various ways that you could use instead.  I just used what i had available.

General JavaScript docs at https://developer.mozilla.org/en/JavaScript, http://msdn.microsoft.com/en-us/library/yek4tbz0(VS.85).aspx.


C. Sowa

Posts: 194
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 10, 2009 5:16 PM PDT   in response to: Jim L Taylor
 
  Click to reply to this thread Reply

With redactions:

GET
ecs.amazonaws.com
/onca/xml
AWSAccessKeyId=XXXXXXXXXXXXXXXXXXXX&AssociateTag=XXXXXXXXXXXXXXXX&ListId=XXXXXXXXXXXXX&ListType=WishList&Operation=ListLookup&ProductPage=1&ResponseGroup=ListInfo&Service=AWSECommerceService&Sort=DateAdded&Timestamp=2009-05-11T00%3A12%3A46Z&Version=2007-10-29


Jim L Taylor

Posts: 2,578
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 10, 2009 7:40 PM PDT   in response to: C. Sowa
 
  Click to reply to this thread Reply

That looks fine and when I replace the XXXX's with my info and run it through my function it works fine. 

Hmmmmmmmmmmm....I see you are send the "strToSign" for the Hashing but I don't see where that variable is being sorted and formatted per the requirements.  I mean, I do see these activities taking place but never being assigned to that variable.

I'm not java expert so I may must be overlooking the changes.

Jim


C. Sowa

Posts: 194
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 10, 2009 8:39 PM PDT   in response to: Jim L Taylor
 
  Click to reply to this thread Reply

strToSign assignment: It's all done in the code block starting "var strToSign = strQuery.replace( ...". The regular expression breaks up the original query, and the replacement function canonicalizes the parameters, constructs & returns the string to be signed, and generates everything in the result query except the signature parameter.

By "works fine", you mean the sample I provided signs properly and is accepted by Amazon, when you use a working encoding function - ? Which would imply that one or more of the URI, Base64 or HMAC-SHA256 encoding functions that I use isn't working properly. That would be bad, since I'm relying on the work of others there. I've tried several alternatives for Base64, none fixed things - which in itself didn't prove anything.

I guess I'll have to compare encoding detail between this and a working example in a different language. Turning into more work than I had hoped, and it's still only shots in the dark. It looks like it should work. And I'm not completely confident that there's nothing undocumented going on over at Amazon that may be affecting the success of this approach, perhaps in conjunction with some quirk of the specific query that I've been using.

Jim L Taylor

Posts: 2,578
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 11, 2009 6:07 AM PDT   in response to: C. Sowa
 
  Click to reply to this thread Reply

Okay.  I see it now.  The "function" is a parameter.

In C# I had to use byte arrays to pass to the hashing function.  I assume the Java solution is different?

Yes.  When I provided valid info in place of the X's and use the Hashing function I posted (C# solution) I can submit the request and get a valid response.

What is the length of the signature that is being returned?


Jim


Aaron Shepard
RealName(TM)


Posts: 71
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 11, 2009 9:29 AM PDT   in response to: Jim L Taylor
 
  Click to reply to this thread Reply

Jim, for the sake of clarity, it's not Java. Despite the name, JavaScript has no relation to Java.

Aaron



Jim L Taylor

Posts: 2,578
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 11, 2009 9:56 AM PDT   in response to: Aaron Shepard
 
  Click to reply to this thread Reply

I know.  I apologize for the poor choice of wording in my response. 

Do you see what might be causing the problem?

Jim


C. Sowa

Posts: 194
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 11, 2009 11:58 AM PDT   in response to: Jim L Taylor
 
  Click to reply to this thread Reply


jimltaylor wrote:
... In C# I had to use byte arrays to pass to the hashing function.  I assume the Java solution is different? ... What is the length of the signature that is being returned?

Ah, hints - just what I was looking for.  On my agenda today was to take a closer look at the UTF-8 encoding and related stuff.  That jssha256.js that I'm using returns a string of hex characters representing the hash bytes - not quite what I need.  What I need instead is to Base64 encode those bytes directly.  Looks like I need to modify one or both of those third party routines to get what I want.  That's not nearly as portable a solution as I had hoped for.

I'll re-post here when I've got this taken care of, hopefully working, or at the next obstacle. 

Thanks again for the feedback.

Jim L Taylor

Posts: 2,578
Registered: 2/8/06
Re: signature authentication with JavaScript?
Posted: May 11, 2009 12:29 PM PDT   in response to: C. Sowa
 
  Click to reply to this thread Reply

Glad to hear my fumbling around was helpful...

Jim



Point your RSS reader here for a feed of the latest messages in all forums