We're using OpenSSL to parse and verify the certificate and signature that Amazon's Alexa sends to external web services, following their list of requirements in the instructions here.
We're successfully extracting the public key, checking the start/end dates of the certificate, verifying that echo-api.amazon.com is the subject of the certificate, and verifying the chain of trust (by using OpenSSL command line functions).
But we're stuck at the point where the Amazon documentation says to "Use the public key extracted from the signing certificate to decrypt the encrypted signature to produce the asserted hash value."
Is this possible with OpenSSL? The openssl "rsautl -decrypt"
command is only for private keys (both the documentation and our tests confirm this, and public keys are rejected, even with the -pubin
option).
Alternately, is there a way to get the openssl dgst -verify
to work for the Alexa signature verification?
We're testing these commands:
openssl base64 -d -in (signature_file) -out /tmp/sign.sha256
openssl dgst -sha256 -verify (pub-key_file) -signature /tmp/sign.sha256 (file)
We've used ColdFusion's getHttpRequestData().headers["Signature"]
function to get the signature:
lOtMJdnw8fffdJHkiM2I6m+K0IqkMCeAWJrjoYGVtkGEBYXUOUazKh6/rpM6opxni7YMHJkA6x5/eGGmWg++VP
0+2I/TNQjR9TTu1LVKikGyi9Oskk/od/tKzEhyWJ2noyyrybqRG1bTSLjVqc1RxDLLRbDuOs12s5F6E0bL18pG
EAww6iMKr2m212wrVzJ2pehp8wVMcqlegOaXW2iFlAunWwte7E/br4vdsYiAXZRLg2uVBDvjmpeo4b9GJZbZkE
HhV+/x+KOwXCISl+Ao0BTr/pzfuF4m/oWpX1PC91hwYMSiVn9I+a+VDxKVxSVllCrffIAIc9mETVuc9U0XRA==
And the Coldfusion GetHttpRequestData().content
function returns the JSON structure sent to the web service:
{
"version":"1.0",
"session":{
"new":true,
"sessionId":"SessionId.29d1522f-6ea6-4aba-b782-f41890388569",
"application":{
"applicationId":"amzn1.ask.skill.63fd6ac5-ed2b-4324-995c-681f96f428a6"
},
"attributes":{
},
"user":{
"userId":"amzn1.ask.account.AHURACZZDQ43ZMUVTOQBEGB5JMWOZCFJRFYXCO26O2IZ3JRS6HYKBOOXPEM6BNWLPUM2E6EWCDC4Q2DPFHXSE3EJT4BLL4CWDNDIFASIHIV2D4AJDH7MDICIFVMHK252EBVQOGFR2TH4HNGMMTPOHI5VGQD7O4UWPZOL2FQOGRCNMVUPUI3SC2R2EH5L5V6XD7B7IF544TYJJCA"
}
},
"request":{
"type":"IntentRequest",
"requestId":"EdwRequestId.d8e9d467-b311-4d9c-8273-9ba0b1e07613",
"timestamp":"2017-05-11T18:49:37Z",
"locale":"en-US",
"intent":{
"name":"GetRssFeedHeadlines",
"slots":{
"RSSFeedLabel":{
"name":"RSSFeedLabel",
"value":"top news"
}
}
}
}
}
Here's the public key:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnK+zBruRA1TnbgQGxE+b
4XiTTZyDkGwJ6068AGsXQmgt9lVhC8CTTC4wdR5NXosboV6/63worQCNo412csBV
jUy3H1/VEs+5Kv+AiAOUuKoBfEU8zAvHCc7GmOKUgNidcDA0MSpx3ZTMSGGbkfaL
ikRzne6nFZ6jNOnkqTtGD6SrCIYgLNArScYoPzIcXEypHFrognzrR4Ee0YcefGZy
S81Yqev/lli01dAgRvpnAty68rYTmxkNhzUSG6IIbFHIxXJKAETAkGiKJcgZpfG2
1Ok5Dk3yGrESY/ID5OnxvMxiXSnXwht8JD6bd15ui0tPDa85B0jpZLloqQZe26oR
owIDAQAB
-----END PUBLIC KEY-----
But the openssl dgst
always returns a message of "Verification Failed" when we use the openssl dgst -verify
with files containing the signature (trying raw and Base64-decoded) and http request body (listed above).