Willing to pay immediately via PayPal for anyone who can solve ASAP,  but only 
if the problem is solved, no partial solutions. 

****************************** 

Background: 
        Code that is about 3 years old, worked fine in older  version of CF 
engine (Blue Dragon Server JX 6).  Code takes a stirng, encypts it to 
HMAC_SHA256 and sends it to  Amazon.  I am 100% certain of the code working 
now, with the exception  of the signature, which is the problem.  

****************************** 

Tools needed: 
        Amazon account - AWSAccessKeyId and Secret Access Key  (Key pair); 
Associate Tag  
        Railo 3 - (I am using 3.3.1)  
        Platform - OS X 10.6 or 10.7 or Ubuntu (using Ubuntu 11.04 Server) but  
problem is seen on both OS X and Unix, so either one will work to  test. 

****************************** 

More info: 
        The code uses two custom functions and creates a signed  request for 
use with Amazon services. Even after updating the URL key  pairs with latest 
(minor) amazon changes, the signature simply is not  matching what Amazon 
expects.  I can use Amazon's tool to check the  URL I generate 
(http://associates-amazon.s3.amazonaws.com/signed-  requests/helper/index.html) 
and then allow Amazon to add the signature  based on my keys, and that works.  
But whenever I try to generate the  signed request in CF it fails.  I can get 
the signed request to work  with a PHP script I downloaded. But I need it in 
CF. 

****************************** 

START ENTIRE CF CODE: 

<!--- function to create your encoded signature ---> 
<cffunction name="HMAC_SHA256" returntype="binary" access="public" 
output="false"> 
        <cfargument name="signKey" type="string" required="true" /> 
        <cfargument name="signMessage" type="string" required="true" /> 
        <cfset var jMsg = 
JavaCast("string",arguments.signMessage).getBytes("iso-8859-1") /> 
        <cfset var jKey = 
JavaCast("string",arguments.signKey).getBytes("iso-8859-1") /> 
        <cfset var key = createObject("java","javax.crypto.spec.SecretKeySpec") 
/> 
        <cfset var mac = createObject("java","javax.crypto.Mac") /> 
        <cfset key = key.init(jKey,"HmacSHA256") /> 
        <cfset mac = mac.getInstance(key.getAlgorithm()) /> 
        <cfset mac.init(key) /> 
        <cfset mac.update(jMsg) /> 
        <cfreturn mac.doFinal() /> 
</cffunction> 


<!--- function to create your url ---> 
<cffunction name="GenerateSignedAmazonURL" returnType="string" output="no"> 
        <!--- parameters ---> 
        <cfargument name="HTTPVerb" required="yes"> 
        <cfargument name="HostHeader" type="string" required="yes"> 
        <cfargument name="HTTPRequestURI" type="string" required="yes"> 
        <cfargument name="SecretAccessKey" type="string" required="yes"> 
        <cfargument name="RawQueryString" type="string" required="yes"> 
        <!--- initialize local var ---> 
        <cfset variables.signature = ""> 
        <cfset variables.encodedQueryString = ""> 
        <cfset variables.sortedQueryString = ""> 
        <cfset variables.encodedSignature = ""> 
        <!--- get your timestamp---> 
        <cfset thenow=dateConvert("local2Utc",now())> 
        <cfset time_stamp = "#DateFormat(thenow,'yyyy-mm- 
dd')#T#TimeFormat(thenow,'HH:mm:ss')#.00Z"> 
        <!--- append timestamp to query string ---> 
        <cfset arguments.RawQueryString = arguments.RawQueryString & 
"&Timestamp=#time_stamp#"> 
        <!--- start building signature ---> 
        <cfset variables.signature = arguments.HTTPVerb & chr(10)> 
        <cfset variables.signature = variables.signature 
&lcase(arguments.HostHeader) & chr(10)> 
        <cfset variables.signature = variables.signature 
&arguments.HTTPRequestURI & chr(10)> 
        <!--- loop over the list and urlEncode each value ---> 
        <cfloop list="#arguments.RawQuerySTring#" delimiters="&" index="i"> 
                <cfset name = listGetAt(i, 1, "=")> 
                <cfset value = ""> 
                <!--- if this item has a value encode it ---> 
                <cfif listLen(i, "=") gt 1> 
                        <cfset value = replace(replace(replace(listGetAt(i, 2, 
"="), ",", "%2C", "ALL"), ":", "%3A", "ALL"), " ", "%20", "ALL")> 
                </cfif> 
                <!--- build the new query string with encoded values ---> 
                <cfset variables.encodedQueryString = 
listAppend(variables.encodedQueryString, "#name#=#value#", "&")> 
        </cfloop> 
        <!--- next we need to canonically order the queryString params ---> 
        <cfset variables.sortedQueryString = 
listSort(variables.encodedQueryString, "textnocase", "asc", "&")> 
        <!--- append to the signature ---> 
        <cfset variables.signature = variables.signature & 
variables.sortedQueryString> 
        <!--- encode the signature ---> 
        <cfset variables.encodedSignature = 
urlencodedformat(toBase64(HMAC_SHA256(arguments.SecretAccessKey, 
variables.signature))) /> 
        <cfreturn "http://#arguments.HostHeader##arguments.HTTPRequestURI#? 
#variables.sortedQueryString#&Signature=#variables.encodedSignature#"> 
</cffunction> 


<!--- generate signed request ---> 
<cfset theHTTPVerb = "GET"> 
<cfset theHostHeader = "ecs.amazonaws.com"> 
<cfset theHTTPRequestURI = "/onca/xml"> 
<cfset theSecretAccessKey = "YOUR-AMAZON-SECRET-ACCESS-KEY"> 

<!--- each param on a new line for readability. order is immaterial here, see 
code source for more options ---> 
<cfset theQueryString = "AWSAccessKeyId=YOUR-AMAZON-ACCESS-KEY-ID" 
& "&AssociateTag=YOUR-AMAZON-ASSOCIATE-ID" 
& "&IdType=ASIN" 
& "&ItemId=iPad2" 
& "&MerchantID=Amazon" 
& "&Operation=ItemLookup" 
& "&ResponseGroup=Large" 
& "&SearchIndex=Electronics" 
& "&Service=AWSECommerceService" 
& "&SignatureMethod=HmacSHA256" 
& "&SignatureVersion=2" 
& "&Version=2011-08-01"> 


<!--- debug ---> 
<cfoutput> 
        <a href="#GenerateSignedAmazonURL(theHTTPVerb, theHostHeader, 
theHTTPRequestURI, theSecretAccessKey, 
theQueryString)#">#GenerateSignedAmazonURL(theHTTPVerb, theHostHeader, 
theHTTPRequestURI, theSecretAccessKey, theQueryString)#</a> 
</cfoutput> 


END ENTIRE CF CODE: 

****************************** 


So, what happens when you run this?  Well, you get an output like this which is 
correct EXCEPT for the signature:   

http://ecs.amazonaws.com/onca/xml?AssociateTag=YOUR-ASSOCIATE-ID&AWSAccessKeyId=YOUR-AWS-ACCESS-JEY&IdType=ASIN&ItemId=iPad2&MerchantID=Amazon&Operation=ItemLookup&ResponseGroup=Large&SearchIndex=Electronics&Service=AWSECommerceService&SignatureMethod=HmacSHA1&SignatureVersion=2&Timestamp=2011-11-10T16%3A32%3A40.00Z&Version=2011-08-01&Signature=Cbojm2j3XyG8i%2FweIT%2Fzkt4uff4wWjcqLHwwg8EkG0I%3D


HOW DO I KNOW THAT THE REQUEST IS CORRECT - - EXCEPT FOR THE SIGNATURE?

Test the code at 

        
http://associates-amazon.s3.amazonaws.com/signed-requests/helper/index.html


...by entering the URL created by the CF code above -  except for the time 
stamp and the signature at the end: 

http://ecs.amazonaws.com/onca/xml?AssociateTag=YOUR-ASSOCIATE-ID&AWSAccessKeyId=YOUR-AWS-ACCESS-JEY&IdType=ASIN&ItemId=iPad2&MerchantID=Amazon&Operation=ItemLookup&ResponseGroup=Large&SearchIndex=Electronics&Service=AWSECommerceService&SignatureMethod=HmacSHA1&SignatureVersion=2&Version=2011-08-01

        remove this part ==> &Timestamp=2011-11-10T16%3A32%3A40.00Z

        and

        remove this part ==> 
&Signature=Cbojm2j3XyG8i%2FweIT%2Fzkt4uff4wWjcqLHwwg8EkG0I%3D


The Amazon request helper will then generate the time stamp and signature for 
you, then cut and paste the final Signed URL that Amazon generates into a 
browser address bar and you will get the XML data back as you should. 

However, if you test your output WITH the signature, you will get: 

<?xml version="1.0"?>
<ItemLookupErrorResponse 
xmlns="http://ecs.amazonaws.com/doc/2011-08-01/";><Error><Code>SignatureDoesNotMatch</Code><Message>The
 request signature we calculated does not match the signature you provided. 
Check your AWS Secret Access Key and signing method. Consult the service 
documentation for 
details.</Message></Error><RequestID>cdddeba5-953a-4315-8248-9bdc0101101e</RequestID></ItemLookupErrorResponse>

****************************** 

Encryption seems to be a major PITA in CF. But the function at the  start of 
this code is Java and so it woudl seem that the problem is  with Java and 
getting Java to generate the correct signature. But, I'm  not a Java pro, so I 
don't know.  This could be as easy as installing the correct Java encryption  
library, but I've not been successful in discovering what that is. So,  if 
that's the problem and you know, well you just made a little cash. 

__________________
Derrick Peavy
[email protected]
404-786-5036

“Innovation distinguishes between a leader and a follower.” - Steve Jobs
"In economics, the majority is always wrong." - John Kenneth Galbraith
"Faced with the choice between changing one’s mind and proving there is no need 
to do so, almost everyone gets busy on the proof." - John Kenneth Galbraith
_____________________







-------------------------------------------------------------

To unsubscribe from this list, manage your profile @ 

http://www.acfug.org?fa=login.edituserform



For more info, see http://www.acfug.org/mailinglists

Archive @ http://www.mail-archive.com/discussion%40acfug.org/

List hosted by http://www.fusionlink.com

-------------------------------------------------------------


Reply via email to