我正在尝试使用 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。