Я внедряю валидатор для проверка входящих запросов от Amazon Alexa. Я на шаге 5 и 6, в котором говорится:
5) base64-декодирует значение заголовка подписи по запросу для получения зашифрованной подписи.
6) Используйте открытый ключ, извлеченный из сертификата подписи, чтобы расшифровать зашифрованную подпись, чтобы получить заявленное значение хеш-функции.
Мне удалось извлечь открытый ключ из сертификата X.509 в кодировке PEM, выполнив:
$publicKey = openssl_pkey_get_public($pem);
$keyData = openssl_pkey_get_details($publicKey);
Который возвращает мой открытый ключ. Затем я попытался расшифровать подпись так:
openssl_public_decrypt(base64_decode($this->signature), $decryptedSignature, $keyData['key']);
Который должен вернуть мне sha1
хэш тела запроса для меня, чтобы сравнить с фактическим телом запроса, но что я получаю от $decryptedSignature
не кажется sha1
хэш. Я надеюсь, что упускаю что-то очевидное, но не вижу этого.
Чтобы сделать вещи немного проще, вот настоящая жизнь base64_encoded
заголовок подписи, возвращенный тестовым сервисом Alexa:
DElCRMK3sXkhmnmu3D2HzVyuLHJ3JkABuBy2LCRX + winUhV6pSC9p1ASKFi9DzESsCyQ74izlFSvi3zECbSbT45bI38JpARJlal81YpWKxz2zTX + y6Qi + мы / bFHHpU4gZO7nTTVQDWG4ua6EuWDTt3jL4B + hPOzO1OKix0jHKQldaTd9meyanttZ5QK7WotBeS6xU + Пум / dmiQ + LM39NERUCrCRyeU07PUdQt + L5PI8MehMz5ClHFOTWgyjE / Дж / b4zrX4weppb / KJhqQVmbw79BWMPuaSwf6BIHyf + 4 + / NSMmoaJ2WMKKEXf1aV7ac71QFFx9pw4P0BX7DK / hqy98Q ==
И вот открытый ключ, извлеченный из https://s3.amazonaws.com/echo.api/echo-api-cert-4.pem:
——НАЧАТЬ ПУБЛИЧНЫЙ КЛЮЧ ——
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnK + zBruRA1TnbgQGxE + Ь
4XiTTZyDkGwJ6068AGsXQmgt9lVhC8CTTC4wdR5NXosboV6 / 63worQCNo412csBV
jUy3H1 / + 5kV виртуальные среды + AiAOUuKoBfEU8zAvHCc7GmOKUgNidcDA0MSpx3ZTMSGGbkfaL
ikRzne6nFZ6jNOnkqTtGD6SrCIYgLNArScYoPzIcXEypHFrognzrR4Ee0YcefGZy
S81Yqev / lli01dAgRvpnAty68rYTmxkNhzUSG6IIbFHIxXJKAETAkGiKJcgZpfG2
1Ok5Dk3yGrESY / ID5OnxvMxiXSnXwht8JD6bd15ui0tPDa85B0jpZLloqQZe26oR
owIDAQAB
—— КОНЕЦ ОБЩЕСТВЕННОГО КЛЮЧА ——
ОК, я понял свою ошибку. Расшифрованная подпись возвращается в двоичном виде, поэтому мне нужно сделать: bin2hex($decryptedSignature)
для того, чтобы получить sha1
хэш. Как ни странно, к возвращенному хэшу подписи добавлено 30 дополнительных символов, поэтому фактическое сравнение хеша Alexa должно быть:
public function compareHashes($pem) {
$publicKey = openssl_pkey_get_public($pem);
openssl_public_decrypt(base64_decode($this->signature), $decryptedSignature, $publicKey);
$decryptedSignature = hex2bin($decryptedSignature);
return sha1($this->responseBody) === substr($decryptedSignature, 30);
}
В любом случае, я открою исходный класс для проверки Alexa и добавлю сюда ссылку после прохождения сертификации Alexa.
редактировать
Сейчас я прошел сертификацию, поэтому вот класс, который я написал для проверки Alexa: https://github.com/craigh411/alexa-request-validator
Других решений пока нет …