代码之家  ›  专栏  ›  技术社区  ›  craig_h

使用openssl\u public\u decrypt对Alexa请求签名进行解密的问题

  •  2
  • craig_h  · 技术社区  · 7 年前

    我正在为实现一个验证器 validating incoming requests from Amazon Alexa

    我已通过以下操作从PEM编码的X.509证书中提取公钥:

    $publicKey = openssl_pkey_get_public($pem);
    $keyData = openssl_pkey_get_details($publicKey);
    

    返回我的公钥。然后,我尝试像这样解密签名:

    openssl_public_decrypt(base64_decode($this->signature), $decryptedSignature, $keyData['key']);
    

    sha1 请求体的散列,以便与实际的请求体进行比较,但我从中得到了什么 $decryptedSignature 沙1

    base64_encoded Alexa测试服务返回的签名头:

    这是从中提取的公钥 https://s3.amazonaws.com/echo.api/echo-api-cert-4.pem :

    Miibijanbgkqhkig9w0baqefaaocaq8amiibcgkcaqueank+zBruRA1TnbgQGxE+b 4XiTTZyDkGwJ6068AGsXQmgt9lVhC8CTTC4wdR5NXosboV6/63worQCNo412csBV jUy3H1/VEs+5Kv+AIAOUKOBFEU8ZAVHCC7GMOKUGNIDDA0MSPX3ZTMSGBKFAL Ikrzne6nfz6jnonkqttgd6srciyglnarscyopzicxeyphfrognzr4ee0ycefgzy S81Yqev/lli01dAgRvpnAty68rYTmxkNhzUSG6IIbFHIxXJKAETAkGiKJcgZpfG2 1ok5d3ygresy/id5onxvmxixsnxwht8jd6bd15ui0tpda85b0jpzlloqze26或 -----结束公钥-----

    1 回复  |  直到 7 年前
        1
  •  2
  •   craig_h    7 年前

    好吧,我已经意识到我的错误了。解密后的签名以二进制形式返回,因此我需要执行以下操作: 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验证类的源代码,并在这里添加一个链接。

    编辑

    https://github.com/craigh411/alexa-request-validator