0

我一直在尝试使用 ColdFusion 实现 Amazon Seller Central API 以获取订单详细信息。API 响应是一个错误,指出

" 我们计算的请求签名与您提供的签名不匹配。请检查您的 AWS Secret Access Key 和签名方法。有关详细信息,请参阅服务文档。"

代码:

<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>
4

0 回答 0