AlexaVerifier

Checking the Signature of the Request

Requests sent by Alexa provide the information you need to verify the signature in the HTTP headers:

To validate the signature:

  1. Verify the URL specified by the SignatureCertChainUrl header value on the request to ensure that it matches the format used by Amazon. See Verifying the Signature Certificate URL.

  2. Download the PEM-encoded X.509 certificate chain that Alexa used to sign the message as specified by the SignatureCertChainUrl header value on the request.

This chain is provided at runtime so that the certificate may be updated periodically, so your web service should be resilient to different URLs with different content.

  1. This certificate chain is composed of, in order, (1) the Amazon signing certificate and (2) one or more additional certificates that create a chain of trust to a root certificate authority (CA) certificate. To confirm the validity of the signing certificate, perform the following checks:
  1. Once you have determined that the signing certificate is valid, extract the public key from it.

  2. Base64-decode the Signature header value on the request to obtain the encrypted signature.

  3. Use the public key extracted from the signing certificate to decrypt the encrypted signature to produce the asserted hash value.

  4. Generate a SHA-1 hash value from the full HTTPS request body to produce the derived hash value

  5. Compare the asserted hash value and derived hash values to ensure that they match.

Verifying the Signature Certificate URL

Before downloading the certificate from the URL specified in the SignatureCertChainUrl header, you should ensure that the URL represents a URL Amazon would use for the certificate. This protects against requests that attempt to make your web service download malicious files and similar attacks.

First, normalize the URL so that you can validate against a correctly formatted URL. For example, normalize

https://s3.amazonaws.com/echo.api/../echo.api/echo-api-cert.pem

to:

https://s3.amazonaws.com/echo.api/echo-api-cert.pem

Next, determine whether the URL meets each of the following criteria:

Examples of correctly formatted URLs:

Examples of invalid URLs:

If the URL does not pass these tests, reject the request and do not proceed with verifying the signature.

TODO

OpenSSL Notes

Generate certificate for testingopenssl req -x509 -newkey rsa:4096 -keyout test/data/key.pem -out test/data/cert.pem -days 2000 -nodes

Create signature (request -> hash) cat test/data/request.json | openssl sha1 > test/data/request_hash (hash -> encrypt -> base64 encode) cat test/data/request_hash | openssl rsautl -sign -inkey test/data/key.pem | openssl base64 -out test/data/request_hash.sign

Verify signature (base64 decode -> decrypt -> compare with request hash) cat test/data/request_hash.sign | openssl base64 -d | openssl rsautl -verify -inkey test/data/cert.pem -certin

Installation

If available in Hex, the package can be installed as:

  1. Add alexa_verifier to your list of dependencies in mix.exs:
```elixir
def deps do
  [{:alexa_verifier, "~> 0.1.0"}]
end
```
  1. Ensure alexa_verifier is started before your application:
```elixir
def application do
  [applications: [:alexa_verifier]]
end
```