![]() |
Chilkat HOME Android™ AutoIt C C# C++ Chilkat2-Python CkPython Classic ASP DataFlex Delphi DLL Go Java Node.js Objective-C PHP Extension Perl PowerBuilder PowerShell PureBasic Ruby SQL Server Swift Tcl Unicode C Unicode C++ VB.NET VBScript Visual Basic 6.0 Visual FoxPro Xojo Plugin
(PureBasic) Verify Signature of Alexa Custom Skill RequestThis example verifies the signature of an Alexa Custom Skill Request. Note: This example requires Chilkat v11.0.0 or greater.
IncludeFile "CkPem.pb" IncludeFile "CkHttp.pb" IncludeFile "CkPublicKey.pb" IncludeFile "CkRsa.pb" IncludeFile "CkCert.pb" IncludeFile "CkStringBuilder.pb" Procedure ChilkatExample() success.i = 0 ; This example assumes you have a web service that will receive requests from Alexa. ; A sample request sent by Alexa will look like the following: ; Connection: Keep-Alive ; Content-Length: 2583 ; Content-Type: application/json; charset=utf-8 ; Accept: application/json ; Accept-Charset: utf-8 ; Host: your.web.server.com ; User-Agent: Apache-HttpClient/4.5.x (Java/1.8.0_172) ; Signature: dSUmPwxc9...aKAf8mpEXg== ; SignatureCertChainUrl: https://s3.amazonaws.com/echo.api/echo-api-cert-6-ats.pem ; ; {"version":"1.0","session":{"new":true,"sessionId":"amzn1.echo-api.session.433 ... }} ; First, assume we've written code to get the 3 pieces of data we need: signature.s = "dSUmPwxc9...aKAf8mpEXg==" certChainUrl.s = "https://s3.amazonaws.com/echo.api/echo-api-cert-6-ats.pem" jsonBody.s = "{" + Chr(34) + "version" + Chr(34) + ":" + Chr(34) + "1.0" + Chr(34) + "," + Chr(34) + "session" + Chr(34) + ":{" + Chr(34) + "new" + Chr(34) + ":true," + Chr(34) + "sessionId" + Chr(34) + ":" + Chr(34) + "amzn1.echo-api.session.433 ... }}" ; To validate the signature, we do the following: ; First, download the PEM-encoded X.509 certificate chain that Alexa used to sign the message http.i = CkHttp::ckCreate() If http.i = 0 Debug "Failed to create object." ProcedureReturn EndIf sbPem.i = CkStringBuilder::ckCreate() If sbPem.i = 0 Debug "Failed to create object." ProcedureReturn EndIf success = CkHttp::ckQuickGetSb(http,certChainUrl,sbPem) If success = 0 Debug CkHttp::ckLastErrorText(http) CkHttp::ckDispose(http) CkStringBuilder::ckDispose(sbPem) ProcedureReturn EndIf pem.i = CkPem::ckCreate() If pem.i = 0 Debug "Failed to create object." ProcedureReturn EndIf success = CkPem::ckLoadPem(pem,CkStringBuilder::ckGetAsString(sbPem),"passwordNotUsed") If success = 0 Debug CkPem::ckLastErrorText(pem) CkHttp::ckDispose(http) CkStringBuilder::ckDispose(sbPem) CkPem::ckDispose(pem) ProcedureReturn EndIf ; The 1st certificate should be the signing certificate. cert.i = CkPem::ckGetCert(pem,0) If CkPem::ckLastMethodSuccess(pem) = 0 Debug CkPem::ckLastErrorText(pem) CkHttp::ckDispose(http) CkStringBuilder::ckDispose(sbPem) CkPem::ckDispose(pem) ProcedureReturn EndIf ; Get the public key from the cert. pubKey.i = CkCert::ckExportPublicKey(cert) If CkCert::ckLastMethodSuccess(cert) = 0 Debug CkCert::ckLastErrorText(cert) CkCert::ckDispose(cert) CkHttp::ckDispose(http) CkStringBuilder::ckDispose(sbPem) CkPem::ckDispose(pem) ProcedureReturn EndIf CkCert::ckDispose(cert) ; Use the public key extracted from the signing certificate to decrypt the encrypted signature to produce the asserted hash value. rsa.i = CkRsa::ckCreate() If rsa.i = 0 Debug "Failed to create object." ProcedureReturn EndIf success = CkRsa::ckUsePublicKey(rsa,pubKey) If success = 0 Debug CkCert::ckLastErrorText(cert) CkPublicKey::ckDispose(pubKey) CkHttp::ckDispose(http) CkStringBuilder::ckDispose(sbPem) CkPem::ckDispose(pem) CkRsa::ckDispose(rsa) ProcedureReturn EndIf CkPublicKey::ckDispose(pubKey) ; RSA "decrypt" the signature. ; (Amazon's documentation is confusing, because we're simply verifiying the signature against the SHA-1 hash ; of the request body. This happens in a single call to VerifyStringENC...) CkRsa::setCkEncodingMode(rsa, "base64") bVerified.i = CkRsa::ckVerifyStringENC(rsa,jsonBody,"sha1",signature) If bVerified = 1 Debug "The signature is verified against the JSON body of the request. Yay!" Else Debug "Sorry, not verified. Crud!" EndIf CkHttp::ckDispose(http) CkStringBuilder::ckDispose(sbPem) CkPem::ckDispose(pem) CkRsa::ckDispose(rsa) ProcedureReturn EndProcedure |
© 2000-2025 Chilkat Software, Inc. All Rights Reserved.