Lua Requires Chilkat v11.0.0+
Lua
Verify Signature of Alexa Custom Skill Request
See more HTTP Misc Examples
This example verifies the signature of an Alexa Custom Skill Request.Chilkat Lua Downloads
local chilkat = require("chilkat")
-- 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:
local signature = "dSUmPwxc9...aKAf8mpEXg=="
local certChainUrl = "https://s3.amazonaws.com/echo.api/echo-api-cert-6-ats.pem"
local jsonBody = "{\"version\":\"1.0\",\"session\":{\"new\":true,\"sessionId\":\"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
local http = chilkat.Http.new()
local sbPem = chilkat.StringBuilder.new()
local success = http:quick_get_sb(certChainUrl, sbPem)
if not success then
print(http.last_error_text)
return
end
local pem = chilkat.Pem.new()
success = pem:load_pem(sbPem:get_as_string(), "passwordNotUsed")
if not success then
print(pem.last_error_text)
return
end
-- The 1st certificate should be the signing certificate.
local cert = ERROR: Method not in Chilkat for Lua: Pem.GetCert
pem:ERROR()
if not pem.last_method_success then
print(pem.last_error_text)
return
end
-- Get the public key from the cert.
local pubKey = chilkat.PublicKey.new()
cert:get_public_key(pubKey)
-- Use the public key extracted from the signing certificate to decrypt the encrypted signature to produce the asserted hash value.
local rsa = chilkat.Rsa.new()
success = rsa:use_public_key(pubKey)
if not success then
print(cert.last_error_text)
return
end
-- 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...)
rsa.encoding_mode = "base64"
local bVerified = rsa:verify_string_enc(jsonBody, "sha1", signature)
if bVerified then
print("The signature is verified against the JSON body of the request. Yay!")
else
print("Sorry, not verified. Crud!")
end