1

我正在尝试使用 Coldfusion 的亚马逊支付 API。在授权中,我不断收到“InvalidRequestSignature”错误。我已正确执行本文档中给出的每个步骤。

我可以在节点 SDK 中成功运行它。我从该响应中获得了 x-amz-pay-date 和 x-amz-pay-idempotency-key,并通过为这些标题静态提供这些来检查 ColdFusion。ColdFusion 中生成的字符串与 node SDK 中生成的字符串相同,如下所示:AMZN-PAY-RSASSA-PSS\nfb972741819aa4124204361d8bf6524b83aca4bc7e2313c4c9da5111dea8743c

我不知道 ColdFusion 上发生了什么。

这是我的规范请求字符串

POST
/v2/checkoutSessions

accept:application/json
content-type:application/json
x-amz-pay-date:2021-09-23T16:28:54Z
x-amz-pay-host:pay-api.amazon.eu
x-amz-pay-idempotency-key:c2e281a1f01c63529d67b838e4bfcffd
x-amz-pay-region:uk

accept;content-type;x-amz-pay-date;x-amz-pay-host;x-amz-pay-idempotency-key;x-amz-pay-region
fa427e08f2b6e529b67275f6e9210101b5538252c42f4f4c7408aafda5050043

仅供参考,如果您在 ColdFusion 中看到此内容,则看不到换行符。

这是我的 StringToSign:

AMZN-PAY-RSASSA-PSS\nfb972741819aa4124204361d8bf6524b83aca4bc7e2313c4c9da5111dea8743c

这是我的错误:

{"reasonCode":"InvalidRequestSignature","message":"Unable to verify signature, signing String [AMZN-PAY-RSASSA-PSS\nc9a4938f623a2904fdea51cg07cd6e6b20ff350c80f20445ba3d5a89fc4077eb] , signature [o7QA2WUEzE6qy7giGirM62LuhxgjFPuzf1+oCnJSgMOTltotF5Gxp2t/oWtms+9myFtsSvT6N0ZNViUckFL3XUPjvDF8QTH+dWKugL2h8147MAN9yt2wORgGYExEk+oqNeUmfMhz0AXZu+wdRsKHs97AbDrMmj9lAbM0Orh5p2xvBVFf5PMYhpSe0a50i7QL+GYSipwNmAXEQOualpkpnVjk6lXhewSMyef2p0XZxnJDE1cyr6iBtWSwCBn4gk17yQGmifJb8joPgYEh3BPQLmHTXOSubJSYxEJZcHYYG35DPIIFqyJEQsJGRlfkVLaS27xjHpzZOTNgyZLMuS1jXQ==]"}

我不确定我是否在 RSA-SHA256 加密算法中犯了错误。我正在关注Ben Nadel 的 RSA-Encrypted Signature Generation

我找不到 ColdFusion 的任何解决方案。这就是我在这里问的原因。提前致谢。

这是我的代码:

<cffunction name="createCanonicalRequest" access="private" returnType="string">
    <cfargument name="requestMethod" type="string" required="true" />
    <cfargument name="originalURI" type="string" required="true" />
    <cfargument name="queryParams" type="struct" required="false" default={} />
    <cfargument name="requestHeaders" type="struct" required="false" default={} />
    <cfargument name="requestPayload" type="string" required="false" default="" />

    <cfset var canonicalRequestMethod = arguments.requestMethod>

    
    <cfset var trimmedURI = len(trim(originalURI)) ? originalURI : "/" & originalURI>
    <cfset var canonicalURI = replace( encodeRFC3986( trimmedURI ), "%2F", "/", "all")>

    
    <cfset var encodedParams = {}>
    <cfscript>
        structEach( queryParams, function(key, value) {
            encodedParams[ encodeRFC3986(arguments.key) ] = encodeRFC3986( arguments.value);
        });
    </cfscript>
    <cfset var encodedKeyNames = structKeyArray( encodedParams )>
    <cfset arraySort( encodedKeyNames, "text" )>
    
    <cfset var encodedPairs  = []>
    <cfscript>
        for (var key in encodedKeyNames) {
            arrayAppend( encodedPairs, key &"="& encodedParams[ key ] );
        }
    </cfscript>
    
    <cfset var canonicalQueryString = arrayToList( encodedPairs, "&")>

    
    <cfset var cleanedHeaders = {}>
    <cfscript>
        structEach( requestHeaders, function(key, value) {
            var headerName = reReplace( trim(arguments.key), "\s+", " ", "all");
            var headerValue = reReplace( trim(arguments.value), "\s+", " ", "all");
            cleanedHeaders[ lcase(headerName) ] = headerValue;
        });
    </cfscript>
    
    <cfset var sortedHeaderNames = structKeyArray( cleanedHeaders )>
    <cfset arraySort( sortedHeaderNames, "text" )>
    
    <cfset var cleanedPairs  = []>
    <cfscript>
        for (var key in sortedHeaderNames) {
            arrayAppend( cleanedPairs, key &":"& cleanedHeaders[ key ] );
        }
    </cfscript>
    
    <cfset var canonicalHeaderString = arrayToList( cleanedPairs, Chr(10) ) & Chr(10)>

    
    <cfset var canonicalSignedHeaderString = arrayToList( sortedHeaderNames, ";" )>

    
    <cfset var canonicalPayloadChecksum = lcase( hash( requestPayload , "SHA256", "UTF-8" ) )>

    
    <cfset var canonicalRequest = canonicalRequestMethod & Chr(10)
                & canonicalURI & Chr(10)
                & canonicalQueryString & Chr(10)
                & canonicalHeaderString & Chr(10)
                & canonicalSignedHeaderString & Chr(10)
                & canonicalPayloadChecksum>

    <cfset var requestDigest = lcase( hash( canonicalRequest , "SHA256", "UTF-8" ) )>

    <cfreturn variables.amazonSignatureAlgorithm & Chr(10) & requestDigest />
</cffunction>

<cffunction name="encodeRFC3986" access="private" returnType="string">
    <cfargument name="text" type="string" required="true" />

    <cfset var encoded = encodeForURL(arguments.text)>
    <cfset encoded = replace( encoded, "%7E", "~", "all" )>
    <cfset encoded = replace( encoded, "+", "%20", "all" )>
    <cfset encoded = replace( encoded, "*", "%2A", "all" )>

    <cfreturn encoded />
</cffunction>

我正在使用上面的 UDF 来创建规范请求。仅供参考,我正在使用 Coldfusion 2016。

4

0 回答 0