Tcl
Tcl
Verify Signature of Alexa Custom Skill Request
See more HTTP Misc Examples
This example verifies the signature of an Alexa Custom Skill Request.Chilkat Tcl Downloads
load ./chilkat.dll
set success 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:
set signature "dSUmPwxc9...aKAf8mpEXg=="
set certChainUrl "https://s3.amazonaws.com/echo.api/echo-api-cert-6-ats.pem"
set 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
set http [new_CkHttp]
set sbPem [new_CkStringBuilder]
set success [CkHttp_QuickGetSb $http $certChainUrl $sbPem]
if {$success == 0} then {
puts [CkHttp_lastErrorText $http]
delete_CkHttp $http
delete_CkStringBuilder $sbPem
exit
}
set pem [new_CkPem]
set success [CkPem_LoadPem $pem [CkStringBuilder_getAsString $sbPem] "passwordNotUsed"]
if {$success == 0} then {
puts [CkPem_lastErrorText $pem]
delete_CkHttp $http
delete_CkStringBuilder $sbPem
delete_CkPem $pem
exit
}
# The 1st certificate should be the signing certificate.
# cert is a CkCert
set cert [CkPem_GetCert $pem 0]
if {[CkPem_get_LastMethodSuccess $pem] == 0} then {
puts [CkPem_lastErrorText $pem]
delete_CkHttp $http
delete_CkStringBuilder $sbPem
delete_CkPem $pem
exit
}
# Get the public key from the cert.
set pubKey [new_CkPublicKey]
CkCert_GetPublicKey $cert $pubKey
delete_CkCert $cert
# Use the public key extracted from the signing certificate to decrypt the encrypted signature to produce the asserted hash value.
set rsa [new_CkRsa]
set success [CkRsa_UsePublicKey $rsa $pubKey]
if {$success == 0} then {
puts [CkCert_lastErrorText $cert]
delete_CkHttp $http
delete_CkStringBuilder $sbPem
delete_CkPem $pem
delete_CkPublicKey $pubKey
delete_CkRsa $rsa
exit
}
# 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_put_EncodingMode $rsa "base64"
set bVerified [CkRsa_VerifyStringENC $rsa $jsonBody "sha1" $signature]
if {$bVerified == 1} then {
puts "The signature is verified against the JSON body of the request. Yay!"
} else {
puts "Sorry, not verified. Crud!"
}
delete_CkHttp $http
delete_CkStringBuilder $sbPem
delete_CkPem $pem
delete_CkPublicKey $pubKey
delete_CkRsa $rsa