0

I have been trying to implement the Amazon Seller Central API for getting the order details, using ColdFusion.The API response is an error stating that the

" 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. "

Code:

<cfcomponent displayname="AmazonOrderDetails">
    <cfoutput>
    <cfset variables.timeStamp = getIsoTimeString(now())>

    <cffunction name="getOrderDetails" access="remote" returntype="any">
        <cfhttp url="https://mws.amazonservices.com/Orders/2013-09-01" method="POST">
            <cfhttpparam name="AWSAccessKeyId" type="url" value="XXXXXXXXXXXXX">
            <cfhttpparam name="Action" type="url" value="ListOrders">
            <cfhttpparam name="Marketplace" type="url" value="XXXXXXXXXXXXXX">
            <cfhttpparam name="Merchant" type="url" value="XXXXXXXXXXXXX">
            <cfhttpparam name="SignatureMethod" type="url" value="HmacSHA256">
            <cfhttpparam name="SignatureVersion" type="url" value="2">  
            <cfhttpparam name="Signature" type="url" value="#generateSignature()#"> 
            <cfhttpparam name="Timestamp" type="url" value="#variables.timeStamp#">
            <cfhttpparam name="Version" type="url" value="2013-09-01">      
            <cfhttpparam name="CreatedAfter" type="url" value="#getIsoTimeString(dateAdd("m", -1, now()))#">    
        </cfhttp>
        <cfdump var="#cfhttp.Filecontent#">
    </cffunction>

    <cffunction name="HMAC_SHA256" returntype="string" access="private" output="false">
        <cfargument name="Data" type="string" required="true" />
        <cfargument name="Key" type="string" required="true" />
        <cfargument name="Bits" type="numeric" required="false" default="256" />

        <cfset local.i = 0 />
        <cfset local.HexData = "" />
        <cfset local.HexKey = "" />
        <cfset local.KeyLen = 0 />
        <cfset local.KeyI = "" />
        <cfset local.KeyO = "" />

        <cfset local.HexData = BinaryEncode(CharsetDecode(Arguments.data, "iso-8859-1"), "hex") />
        <cfset local.HexKey = BinaryEncode(CharsetDecode(Arguments.key, "iso-8859-1"), "hex") />
        <cfset local.KeyLen = Len(local.HexKey)/2 />

        <cfif local.KeyLen gt 64>
            <cfset local.HexKey = Hash(CharsetEncode(BinaryDecode(local.HexKey, "hex"), "iso-8859-1"), "SHA-256", "iso-8859-1") />
            <cfset local.KeyLen = Len(local.HexKey)/2 />
        </cfif>

        <cfloop index="i" from="1" to="#KeyLen#">
            <cfset local.KeyI = local.KeyI & Right("0"&FormatBaseN(BitXor(InputBaseN(Mid(local.HexKey,2*i-
        1,2),16),InputBaseN("36",16)),16),2) />
            <cfset local.KeyO = local.KeyO & Right("0"&FormatBaseN(BitXor(InputBaseN(Mid(local.HexKey,2*i-
        1,2),16),InputBaseN("5c",16)),16),2) />
        </cfloop>

        <cfset local.KeyI = local.KeyI & RepeatString("36",64-local.KeyLen) />
        <cfset local.KeyO = local.KeyO & RepeatString("5c",64-local.KeyLen) />

        <cfset local.HexKey = Hash(CharsetEncode(BinaryDecode(local.KeyI&local.HexData, "hex"), "iso-8859-1"), "SHA-256", "iso-8859-1")
        />
        <cfset local.HexKey = Hash(CharsetEncode(BinaryDecode(local.KeyO&local.HexKey, "hex"), "iso-8859-1"), "SHA-256", "iso-8859-1") />

        <cfreturn Left(local.HexKey,arguments.Bits/4) />
    </cffunction>

    <cffunction name="getIsoTimeString" returntype="Any" access="private">
        <cfargument name="datetime" type="date" required="true">
        <cfset local.convertToUTC = true>
        <cfif local.convertToUTC >
            <cfset local.datetime = dateConvert( "local2utc", arguments.datetime )>
            <cfreturn(
                dateFormat( local.datetime, "yyyy-mm-dd" )&"T"&timeFormat( local.datetime, "HH:mm:ss" )&"Z"
            )>
        </cfif>
    </cffunction>

    <cffunction name="generateSignature" returntype="String" access="private">
        <cfset local.secret_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">

        <cfset parameters = structNew() >
        <cfset parameters["xxxxxxxxxxxxxxxxxxxx"] = "UserID">
        <cfset parameters["1.0"] = "Version">
        <cfset parameters["ListOrders"] = "Action">
        <cfset parameters["#variables.timeStamp#"] = "Timestamp">
        <cfset local.strtohash = "" >
        <cfloop list="#ArrayToList(StructSort(parameters, "text", "asc"))#" index="key" >
            <cfset local.strtohash = local.strtohash & #parameters[key]# & "=" & #URLEncodedFormat(key)# & "&" >
        </cfloop>
        <cfset local.strtohash = RemoveChars(local.strtohash, len(local.strtohash), 1)>
        <cfset local.strtohash = Replace(local.strtohash, "%2D", "-", "All")>
        <cfset local.strtohash = Replace(local.strtohash, "%2E", ".", "All")>
        <cfset local.signature="#LCase(toBase64(HMAC_SHA256(local.strtohash, local.secret_key)))#"> 
        <cfreturn local.signature>  
    </cffunction>

    </cfoutput>
</cfcomponent>
Leigh
  • 28,765
  • 10
  • 55
  • 103
Eldho K V
  • 1
  • 2
  • 2
    Did you _Check your AWS Secret Access Key and signing method_? That error message is fairly specific. We cannot help you without more detail. – Miguel-F Feb 08 '17 at 12:47
  • 1
    I'm voting to close this question as off-topic because the person asking the question has shown no effort to solve it himself. – Dan Bracuk Feb 08 '17 at 13:39
  • @DanBracuk Is there any way to check the signature calculated? – Eldho K V Feb 08 '17 at 14:14
  • @Miguel-F I have added the code. – Eldho K V Feb 08 '17 at 14:23
  • A) What is your CF version? B) Which signature format: 2 or 4? Can you post the URL for the Seller API explaining the steps you are trying to match? – Leigh Feb 08 '17 at 14:45
  • @Leigh A)Coldfusion 2016 – Eldho K V Feb 08 '17 at 15:07
  • (Edit) What about the URL? Most of their API's have a public url explaining how to calculate signatures. (I assume that is what the above code is based on). *Is there any way to check the signature calculated* Amazon often provides verification tools for API's. Check the API docs. – Leigh Feb 08 '17 at 15:12
  • @Leigh B) 2 C) https://mws.amazonservices.com/Orders/2013-09-01?AWSAccessKeyId=XXXXXXXX&CreatedAfter=2016-12-16T09:08:09Z&Action=ListOrders&Marketplace=XXXXXXX&Merchant=XXXXXXXXX&SignatureMethod=HmacSHA256&SignatureVersion=2&Signature=64e11a27ef4419f8efce3067d74a976a5851e1dce37d5d47aebe291898d4100f&Timestamp=2017-01-16T09:08:09Z&Version =2013-09-01 – Eldho K V Feb 08 '17 at 15:15
  • @EldhoKV - No, I mean their developer documentation explaining how signatures for that API should be calculated. For example http://docs.aws.amazon.com/general/latest/gr/signature-version-2.html . What did you use to create the functions above? – Leigh Feb 08 '17 at 15:18
  • @Leigh I had contacted Amazon support but they said there is no way to check the signature calculated. – Eldho K V Feb 08 '17 at 15:18
  • So what AWS documentation did you use to create the functions above? – Leigh Feb 08 '17 at 15:33
  • @ Leigh I found a pdf online – Eldho K V Feb 08 '17 at 15:46
  • @EldhoKV They provide signature troubleshooting documentation. They recommend you use Signature Version 4. [Troubleshooting AWS Signature Version 4 Errors](http://docs.aws.amazon.com/general/latest/gr/signature-v4-troubleshooting.html). The troubleshooting steps for Signature Version 2 are toward the bottom of this page [Signature Version 2 Signing Process](http://docs.aws.amazon.com/general/latest/gr/signature-version-2.html). – Miguel-F Feb 08 '17 at 15:51
  • @EldhoKV - And the url for that pdf would be ... ? ;-) – Leigh Feb 08 '17 at 16:41
  • @Leigh https://forum.opencart.com/download/file.php?id=24613 – Eldho K V Feb 08 '17 at 16:46
  • I think you may be going down the wrong path. Not sure what product that is, but better to use Amazon's own documentation. I am not familiar with MWS, but a quick search turned up: [MWS API Documentation](http://docs.developer.amazonservices.com/en_US/dev_guide/). Like the links Miguel-F and I posted, it explains how to construct a signature. Also, do a search on "ColdFusion Amazon signature". There are several articles on signatures and few udf's you could adapt. The general process is the same for all Amazon API's, only the parameters for each API differ. – Leigh Feb 08 '17 at 17:19

0 Answers0