【问题标题】:Invalid signature error in Amazon AWS API "itemsearch" call using ColdFusion使用 ColdFusion 的 Amazon AWS API“itemsearch”调用中的无效签名错误
【发布时间】:2018-06-05 19:54:12
【问题描述】:

我遇到了一个错误,即无效签名。我正在调用 itemsearch API,但在此之前我的签名(第 4 版)不起作用。

这是我从http://amazonsig.riaforge.org/index.cfm?event=action.download得到的cfc文件“amazonsig.cfc”:

<cfcomponent hint="Amazon Product Advertising API Signature Generator">

    <cffunction name="signRequest" returntype="string" output="false"
        hint="Sign a request">

        <cfargument name="request" required="yes" type="string">
        <cfargument name="secretKey" required="yes" type="string">

        <!--- "Local" variable scope --->
        <cfset var lc = structnew()>

        <!--- Extract the URL part of the request and strip the protocol --->
        <cfset lc.requesturl = listfirst(arguments.request, "?")>
        <cfset lc.requesturl = replacenocase(lc.requesturl, "http://", "")>

        <!--- Split into host and path --->
        <cfset lc.host = listfirst(lc.requesturl, "/")>
        <cfset lc.path = right(lc.requesturl, len(lc.requesturl) - len(lc.host))>

        <!--- Process the query string parameters into a structure --->
        <cfset lc.querystring = listlast(arguments.request, "?")>
        <cfset lc.strParams = structnew()>
        <cfloop list="#lc.querystring#" index="i" delimiters="&">
            <cfset lc.strParams[listfirst(i, "=")] = urldecode(listlast(i, "="))>
        </cfloop>

        <!--- Add the timestamp --->
        <cfif not StructKeyExists(lc.strParams, "Timestamp")>
            <cfset lc.utcdate = dateconvert("local2Utc", now())>
            <cfset lc.timestamp = dateformat(lc.utcdate, 'yyyy-mm-dd') & "T" & timeformat(lc.utcdate, 'HH:mm:ss') & "Z">
            <cfset lc.strParams["Timestamp"] = lc.timestamp>
        </cfif>

        <!--- Sort the parameters --->
        <cfset lc.keys = listsort(structkeylist(lc.strParams), "text")>

        <!--- Generate a new query string including timestamp, with parameters in the correct order, encoding as we go --->
        <cfset lc.qs = "">
        <cfloop list="#lc.keys#" index="i">
            <cfset lc.qs = lc.qs & rfc3986EncodedFormat(i) & "=" & rfc3986EncodedFormat(lc.strParams[i]) & "&">
        </cfloop>

        <!--- Strip off the last & --->
        <cfset lc.qs = left(lc.qs, len(lc.qs)-1)>

        <!--- Build the string to sign --->
        <cfset lc.stringToSign = "GET" & chr(10)>
        <cfset lc.stringToSign = lc.stringToSign & lc.host & chr(10)>
        <cfset lc.stringToSign = lc.stringToSign & lc.path & chr(10)>
        <cfset lc.stringToSign = lc.stringToSign & lc.qs>

        <!--- Create the signature --->
        <cfset lc.binaryMsg = JavaCast("string",lc.stringToSign).getBytes("iso-8859-1")>
        <cfset lc.binaryKey = JavaCast("string",arguments.secretKey).getBytes("iso-8859-1")>
        <cfset lc.key = createObject("java","javax.crypto.spec.SecretKeySpec")>
        <cfset lc.key.init(lc.binaryKey,"HmacSHA256")>
        <cfset lc.hmac = createObject("java","javax.crypto.Mac")>
        <cfset lc.hmac = lc.hmac.getInstance("HmacSHA256")>
        <cfset lc.hmac.init(lc.key)>
        <cfset lc.hmac.update(lc.binaryMsg)>
        <cfset lc.signature = lc.hmac.doFinal()>

        <!--- Return the new request URL --->
        <cfreturn "http://" & lc.host & lc.path & "?" & lc.qs & "&Signature=" & urlencodedformat(tobase64(lc.signature))>

    </cffunction>

    <cffunction name="rfc3986EncodedFormat" returntype="string" output="false"
        hint="Perform some character encoding">
        <cfargument name="text" required="yes" type="string">
        <!--- "Local" variable scope --->
        <cfset var lc = structnew()>
        <cfset lc.objNet = createObject("java","java.net.URLEncoder")>
        <cfset lc.encodedText = lc.objNet.encode(arguments.text, 'utf-8').replace("+", "%20").replace("*", "%2A").replace("%7E", "~")>
        <cfreturn lc.encodedText>
    </cffunction>
</cfcomponent>

这是我的 cfm 文件“amazonsig.cfm”

<cfset requrl = "http://webservices.amazon.com/onca/xml?Service=AWSECommerceService&Operation=ItemSearch&AWSAccessKeyId=aaaa&AssociateTag=aaaaa&SearchIndex=Books&Keywords=Harry&ResponseGroup=Images,ItemAttributes,Offers">

<cfset amazonsig = createObject("component", "amazonsig")>
<cfset abc = amazonsig.signrequest(requrl,"aaa")>


<cfhttp url="#abc#" method="GET" result="response"  resolveurl="yes">
<cfhttpparam type="header" name="Content-Type" value="application/json" >
<cfhttpparam type="header" name="Accept" value="application/json" >

</cfhttp>
<cfdump var="#response#">

注意:签名URL是正确的,因为我直接在浏览器中点击并且响应正确返回,但是在中它给出了错误。

【问题讨论】:

  • 问题不清楚。签名非常细腻。如果没有更多信息,就不可能说出为什么您会收到无效签名错误。哪个API?需要什么签名版本?导致错误的确切代码是什么(当然省略任何“秘密”值)?确切的错误信息和代码是什么?
  • @Leigh 首先我尝试了一种捷径。我从“itemsearch”api webservices.amazon.com/scratchpad/index.html 的亚马逊便笺本示例中获得了 php 代码,然后将生成的签名放在 php 中的 标记中,它就像一个魅力,但相同的签名在冷融合中不起作用。它应该工作。
  • 您仍然没有回答上述问题,或者on your other thread。不幸的是,在没有更多信息的情况下,任何人都只能在这一点上猜测。请参阅How to AskHow to create a Minimal, Complete, and Verifiable example
  • @Leigh 我已经提供了每一个细节。你现在说什么???
  • @Leigh 等待您的回复。

标签: api amazon-web-services coldfusion aws-sdk


【解决方案1】:

确保您使用最新版本的 Java 运行 ColdFusion。许多 CF 安装使用的是较旧的 JVM,这些 JVM 不支持许多 Web 服务正在使用的更新的安全功能。

这里是 blog post,其中包含为 ColdFusion 更新 Java 的说明。

【讨论】:

  • @P Mascari 我正在使用 CF 11 和 jdk 1.8
【解决方案2】:

我已经解决了,我在 jdk 1.7 上使用了 Coldfusion 11,但是当我在带有 jdk 1.8 的 Coldfusion 10 上运行代码时,它成功运行了。

【讨论】:

  • 这正是@P-Mascari 在他们的回答中告诉你的 - 最新版本的 Java。您可能希望接受这个问题的答案。
  • @Miguel-F 不,我炸了,这不是。我想在当前版本上运行代码。这不是解决方案。我想让它在coldfusion 11和jdk 1.7上工作。
  • 但问题是 jdk 1.7 不支持它。这不是 ColdFusion 问题,而是 JRE 问题。对 Java 1.7 的支持就像两年前一样结束,ColdFusion 10 支持在本月结束。你需要更新。亚马逊只支持最新的安全标准是有原因的。
猜你喜欢
  • 1970-01-01
  • 2020-11-06
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多