亚马逊有关如何验证的文档发布在此处:https://developer.amazon.com/docs/custom-skills/host-a-custom-skill-as-a-web-service.html#checking-the-signature-of-the-request
我一直试图让它发挥作用:
确定签名证书有效后,从中提取公钥。
Base64-解码请求上的Signature标头值以获取加密签名。
使用从签名证书中提取的公钥来解密加密签名,以生成声明的哈希值。
从完整HTTPS请求正文生成SHA-1哈希值,以生成派生哈希值
比较断言的哈希值和派生的哈希值,以确保它们匹配。
这是我到目前为止所拥有的。我已经完成了主题和有效的pem文件的验证,问题是我不知道如何'比较断言的哈希值和派生的哈希值以确保它们匹配。
<!---get the request sent from amazon---->
<cfset local.request = deserializeJson(
toString(getHttpRequestData().content)
)>
<!---collect headers for authentication---->
<cfif this.isTesting is False>
<cftry>
<cfset local.request.headers.SignatureCertChainUrl = getHttpRequestData().headers.SignatureCertChainUrl>
<cfcatch type="any">
<cfset local.request.request.type = "SessionEndedRequest"><!---end session if SignatureCertChainUrl not passed--->
</cfcatch>
</cftry>
<cftry>
<cfset local.request.headers.Signature = getHttpRequestData().headers.Signature>
<cflog file="Alexa" text="URL Sig: #local.request.headers.Signature#" >
<cfcatch type="any">
<cfset local.request.request.type = "SessionEndedRequest"><!---end session if Signature not passed--->
<cflog file="Alexa" text="Signature is not defined" >
</cfcatch>
</cftry>
<cfif isDefined("local.request.headers.SignatureCertChainUrl") and
isDefined("local.request.headers.Signature")>
<cfif find('https://s3.amazonaws.com/echo.api/',local.request.headers.SignatureCertChainUrl)
or find('https://s3.amazonaws.com:443/echo.api/',local.request.headers.SignatureCertChainUrl)><!---not ssl so kill it--->
<cflog file="Alexa" text="URL Chain: #local.request.headers.SignatureCertChainUrl#" >
<cfset local.request.headers.SignatureCertChainUrlFormatted = replacenocase(local.request.headers.SignatureCertChainUrl,'echo.api/../echo.api','echo.api')>
<cfhttp url="#local.request.headers.SignatureCertChainUrlFormatted#" method="get"></cfhttp>
<cffile action="write"
file="C:\inetpub\alexa\cert\echo.pem"
output="#cfhttp.FileContent#">
<!---check date is valid---->
<cfexecute name="C:\OpenSSL-Win32\bin\openssl.exe"
arguments="x509 -noout -dates -in C:\inetpub\alexa\cert\echo.pem"
variable="local.cert.OpenSSL_dates"
timeout="10" >
</cfexecute>
<cfset local.cert.datesFormatted = replacenoCase(local.cert.OpenSSL_dates,'notbefore','')>
<cfset local.cert.datesFormatted = replacenoCase(local.cert.datesFormatted,'notafter','')>
<cfset local.cert.datesFormatted = replacenoCase(local.cert.datesFormatted,'=','')>
<cfset local.cert.notBefore = trim(listgetat(local.cert.datesFormatted,1,'='))>
<cfset local.cert.notAfter = trim(listgetat(local.cert.datesFormatted,2,'='))>
<cfif datecompare(convertCertTime(local.cert.notBefore),now()) is '-1' and
datecompare(convertCertTime(local.cert.notAfter),now()) is '1'>
<!---cert date is valid--->
<cfelse>
<cfset local.request.request.type = "SessionEndedRequest">
</cfif>
<!---check 'echo-api.amazon.com' in subject---->
<cfexecute name="C:\OpenSSL-Win32\bin\openssl.exe"
arguments="x509 -noout -subject -in C:\inetpub\alexa\cert\echo.pem"
variable="local.cert.OpenSSL_Subject"
timeout="10" >
</cfexecute>
<cfif NOT findNOcase('echo-api.amazon.com',local.cert.OpenSSL_Subject)>
<cfset local.request.request.type = "SessionEndedRequest">
</cfif>
<!---check 'CN=Symantec Class 3 Secure Server CA' in issuer---->
<cfexecute name="C:\OpenSSL-Win32\bin\openssl.exe"
arguments="x509 -noout -issuer -in C:\inetpub\alexa\cert\echo.pem"
variable="local.cert.OpenSSL_issuer"
timeout="10" >
</cfexecute>
<cfif NOT findNOcase('Symantec Class 3 Secure Server CA',local.cert.OpenSSL_issuer)>
<cfset local.request.request.type = "SessionEndedRequest">
</cfif>
<cfexecute name="C:\OpenSSL-Win32\bin\openssl.exe"
arguments="x509 -noout -pubkey -in C:\inetpub\alexa\cert\echo.pem"
variable="local.cert.OpenSSL_Pubkey"
timeout="120" >
</cfexecute>
<cffile action="write"
file="C:\inetpub\alexa\keys\#local.request.request.requestId#.key"
output="#local.cert.OpenSSL_Pubkey#">
<!---decyrpt header signature---->
<!----Base64-decode the Signature header---->
<cfset local.cert.encryptedSig = toString(ToBinary(local.request.headers.Signature)) />
<cffile action="write"
file="C:\inetpub\alexa\keys\#local.request.request.requestId#.sig"
output="#local.cert.encryptedSig#">
<cfelse>
<cfset local.request.request.type = "SessionEndedRequest">
</cfif>
<!----end of header decrypting----->
<cfelse>
<!---if either of these are not defined kill the session---->
<cfset local.request.request.type = "SessionEndedRequest">
</cfif>
</cfif>
答案 0 :(得分:-1)
在Base64解码之前尝试将charsetDecode转换为utf-8
答案 1 :(得分:-1)
在Base64解码之前使用它
<CFSET local.request.headers.Signature = charsetDecode( local.request.headers.Signature, "utf-8" )>