Closed briward closed 2 years ago
Hey Bri,
I'm not the original creator, nor anything to do with this package, however I have merged quite a few developments from various people into my own fork here https://github.com/danstreeter/amazon-alexa-php
I've certainly not had that error using the merged copy...
You can see what has been merged here: https://github.com/jakubsuchy/amazon-alexa-php/network
All the best
Dan
Hey Dan,
Ah I see, I think i've somehow become lost in forks here. I've now pulled your fork down and sadly the error persists. Does the "Service Simulator" (on Amazon developer interface) work for you when using the package?
Best wishes, Bri
Hmm, thats odd - I've got 'my' package working in three different skills at the moment without any problems, I doubt that amazon are having any service issues (given they are AWS! haha)...
Do you get any other information with regards to the error? Anything more in the error logs?
With regards to the replay attack: change the timestamp of your test message to something in the future (I have mine set to 2117 as there seems to be no upper bound checking).
ha, yeah seems pretty strange. It could be something totally simple (hopefully!)
Sadly the main issue I have is the lack of errors in my logs, I've managed to get around the other two issues locally by changing timestamp and commenting out a few things.
I'll keep plowing through and see if I can get any more log messages.
Thanks
What are you incorporating the package into?
I've got the package running inside a SlimPHP app, on an nginx, Ubuntu (DO) server. Nothing particularly fancy really.
I've now managed to get the following:
Type: InvalidArgumentException Message: Request signature could not be verified File: akubsuchy/amazon-alexa-php/src/Request/Certificate.php Line: 90
So it looks like it may be having some problems with the openssl_verify check perhaps?
I'm using Let's Encrypt for SSL.
Are you sending the required header with the certificate path?
Quite possibly not, I don't suppose you have any examples there?
The documentation for it is here: https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/developing-an-alexa-skill-as-a-web-service
However my payload is as follows:
Headers:
signaturecertchainurl == https://s3.amazonaws.com/echo.api/echo-api-cert-4.pem
signature == (base64string)
JSON Payload:
{ "session": { "sessionId": "SessionId.4f9bb0a5-7afe-4b2b-af5a-dbefff8183c3", "application": { "applicationId": "(application ID)" }, "attributes": {}, "user": { "userId": "amzn1.ask.account.xxxxxxx..." }, "new": true }, "request": { "type": "IntentRequest", "requestId": "EdwRequestId.1163cdd2-bcce-4d60-acaf-f3d3484c3fd1", "locale": "en-GB", "timestamp": "2016-12-27T23:59:42Z", "intent": { "name": "AskToCount", "slots": { "CountTo": { "name": "CountTo", "value": "10" } } } }, "version": "1.0" }
Ah, i'm actually just using the built-in "Service Simulator" so i'm hoping that is sending the correct headers when it makes a request to my server.
It should be doing so yes, if your referring to the one under the Alexa Skills Kit > Test > Service Simulator.
I've never had inbound certificate issues with that one, only when I use a static payload from Postman do I need to 'return true;' from the Certificate class to ignore the invalid digest.
Can you use the following http://docs.slimframework.com/request/headers/ to get all the headers to check? (Presuming of course that this is the SlimPHP that your using)
I doubt it is that though to be honest, and would point toward the built in PHP open_ssl methods - I've had problems in the past when implementing them against a Java SOAP client request and the digest's just 'not matching' despite running through the correct routines...
My point to start would be to start throwing out some debug in the Certificate.php:: validateRequestSignature() method to ensure its getting the right content at all the right places. (Bear in mind however that some of this will be binary data)
Looks like the openssl_pkey_get_public() function is returning nothing. This may be the problem.
$this->certificateContent
and $this->requestSignature
both appear to be returning correct values though.
Sounds about right as that will be then used to digest the message and provide a matching signature. Without that - it'll stump itself =(
Perhaps my certificate is not X.509 (i'm not particularly knowledgeable in this area yet sadly) and therefor can't export the key from it.
You shouldnt have to be providing one as the consumer of inbound requests from ASK, they send you theirs and you validate it.
(I cant find my link to an easy to read version) but in summary: They get the data they want to send and create a digest by 'mashing' it using their PRIVATE key. They then send you the message incusive of this digest (now called signature) as part of the message, public on the line. They also send you a resource to get their public key (given in the header). You then take the public key and 'mash' the same data and you should end up with the same digest.
This prooves that the message has not changed in transit as no one but THEY can create it - anyone can confirm that they created it.
This is different to your SSL certificate, which although is of similar format, used for a different purpose. That has nothing to do with the communication between you, digest calculation, signature validation or anything to do with the messaging at all. The SSL certificate gives you encryption 'during transmission' whilst on the line.
SSL for HTTPS protects you against man in the middle & sniffing SSL for webservice messaging protects you against message replay (coupled with timestamp data which is part of the digest) and the messaging being changed 'in transit' should the HTTPS failed (unlikely)
Anyway... back to your issue... what version of PHP and openssl are you using on the server?
Ah, thanks I appreciate the explanation. I have PHP 7.0.13 and OpenSSL 1.0.2g installed on my server.
I'm on PHP 5.6 and OpenSSL 1.0.2j in one of my development enviroments that works fine... I dont see any major changes between OpenSSL 1.0.2g > j (none that I can make any sense of anyway) https://www.openssl.org/news/openssl-1.0.2-notes.html.
And i've not tried it on PHP7 as yet so cant comment on that. =(
Just to let you know I eventually solved my problem. Turns out I was actually re-encoding the JSON request and passing that in to verify, but by doing that I was changing the request and therefor invalidating it. Doh!
Simple ones are always the hardest 👍
Agh - yeh... that'll do it! =) Glad you got it sorted though.
I had a similar thing in the past with the ordering of things happening, turns out (obviously now) that you cant add things to a message once the digest has been calculated! Doh!
Hi,
I've just started using the package, thanks very much for providing it! However, I wonder if you have experienced the same issue as me. I have followed the code examples but I keep getting a 500 error when testing via the Amazon developer hub.
Error:
There was an error calling the remote endpoint, which returned HTTP 500 : Internal Server Error
If I test locally I get the following messages logged:
[2017-01-17 13:03:10] logger.CRITICAL: Request timestamp was too old. Possible replay attack. [] []
[2017-01-17 13:03:30] logger.CRITICAL: Protocol isn't secure. Request isn't from Alexa. [] []
So that makes me think I have everything setup correctly, as it shouldn't work locally.
Best wishes, Bri