SQL Server
SQL Server
Verify Signature of Alexa Custom Skill Request
See more HTTP Misc Examples
This example verifies the signature of an Alexa Custom Skill Request.Chilkat SQL Server Downloads
-- Important: See this note about string length limitations for strings returned by sp_OAMethod calls.
--
CREATE PROCEDURE ChilkatSample
AS
BEGIN
DECLARE @hr int
DECLARE @iTmp0 int
-- Important: Do not use nvarchar(max). See the warning about using nvarchar(max).
DECLARE @sTmp0 nvarchar(4000)
DECLARE @success int
SELECT @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:
DECLARE @signature nvarchar(4000)
SELECT @signature = 'dSUmPwxc9...aKAf8mpEXg=='
DECLARE @certChainUrl nvarchar(4000)
SELECT @certChainUrl = 'https://s3.amazonaws.com/echo.api/echo-api-cert-6-ats.pem'
DECLARE @jsonBody nvarchar(4000)
SELECT @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
DECLARE @http int
EXEC @hr = sp_OACreate 'Chilkat.Http', @http OUT
IF @hr <> 0
BEGIN
PRINT 'Failed to create ActiveX component'
RETURN
END
DECLARE @sbPem int
EXEC @hr = sp_OACreate 'Chilkat.StringBuilder', @sbPem OUT
EXEC sp_OAMethod @http, 'QuickGetSb', @success OUT, @certChainUrl, @sbPem
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @http, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @http
EXEC @hr = sp_OADestroy @sbPem
RETURN
END
DECLARE @pem int
EXEC @hr = sp_OACreate 'Chilkat.Pem', @pem OUT
EXEC sp_OAMethod @sbPem, 'GetAsString', @sTmp0 OUT
EXEC sp_OAMethod @pem, 'LoadPem', @success OUT, @sTmp0, 'passwordNotUsed'
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @pem, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @http
EXEC @hr = sp_OADestroy @sbPem
EXEC @hr = sp_OADestroy @pem
RETURN
END
-- The 1st certificate should be the signing certificate.
DECLARE @cert int
EXEC sp_OAMethod @pem, 'GetCert', @cert OUT, 0
EXEC sp_OAGetProperty @pem, 'LastMethodSuccess', @iTmp0 OUT
IF @iTmp0 = 0
BEGIN
EXEC sp_OAGetProperty @pem, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @http
EXEC @hr = sp_OADestroy @sbPem
EXEC @hr = sp_OADestroy @pem
RETURN
END
-- Get the public key from the cert.
DECLARE @pubKey int
EXEC @hr = sp_OACreate 'Chilkat.PublicKey', @pubKey OUT
EXEC sp_OAMethod @cert, 'GetPublicKey', @success OUT, @pubKey
EXEC @hr = sp_OADestroy @cert
-- Use the public key extracted from the signing certificate to decrypt the encrypted signature to produce the asserted hash value.
DECLARE @rsa int
EXEC @hr = sp_OACreate 'Chilkat.Rsa', @rsa OUT
EXEC sp_OAMethod @rsa, 'UsePublicKey', @success OUT, @pubKey
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @cert, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @http
EXEC @hr = sp_OADestroy @sbPem
EXEC @hr = sp_OADestroy @pem
EXEC @hr = sp_OADestroy @pubKey
EXEC @hr = sp_OADestroy @rsa
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...)
EXEC sp_OASetProperty @rsa, 'EncodingMode', 'base64'
DECLARE @bVerified int
EXEC sp_OAMethod @rsa, 'VerifyStringENC', @bVerified OUT, @jsonBody, 'sha1', @signature
IF @bVerified = 1
BEGIN
PRINT 'The signature is verified against the JSON body of the request. Yay!'
END
ELSE
BEGIN
PRINT 'Sorry, not verified. Crud!'
END
EXEC @hr = sp_OADestroy @http
EXEC @hr = sp_OADestroy @sbPem
EXEC @hr = sp_OADestroy @pem
EXEC @hr = sp_OADestroy @pubKey
EXEC @hr = sp_OADestroy @rsa
END
GO