Не удалось подтвердить подпись при покупке в Google Play

У меня есть серверная часть на PHP, которая интегрируется с сервисами Google Play для проверки покупки, сделанной из приложения. Информация о покупке возвращает квитанцию ​​​​и подпись, и мне нужно проверить правильность покупки.

Я получаю:

{ 
   ...rest of the data,
   receipt": {
      "orderId":"...",
      "packageName": ...,
      "productId":" ...,
      "purchaseTime": ...,
      "purchaseState": 0,
      "purchaseToken": ...,
      "autoRenewing": true
   },
"signature": ...
}

И я использую открытый ключ, расположенный в консоли Google Play, для проверки подписи. Я отформатировал его в PEM вручную, добавив -----BEGIN PUBLIC KEY----- и -----END API KEY----. Я также разделил строки на куски по 64 и проверил, что открытый ключ соответствует правильному проекту.

Наконец, я использую библиотеку phpseclib для выполнения проверки, но она продолжает давать сбой.

    $receipt= $transaction['receipt'];
    $rsa = new RSA();
    $rsa->loadKey(Yii::$app->params['public_key']);
    $verify = $rsa->verify(json_encode($receipt), $signature);

Я кодирую квитанцию, потому что методу проверки нужна строка, но я не уверен в этом шаге. Делаю это из тестовой среды, поэтому покупка не реальна. Я подозреваю, что открытый ключ как-то неверен, но я получил его из Инструменты разработки> Сервисы и API> Лицензирование и выставление счетов за приложения. Что может быть не так?


person Carlos Isidoro López    schedule 16.12.2019    source источник
comment
Я проверил, что phpseclib ожидает подпись длиной 256, но та, которую возвращает Google Play, имеет 341 символ.   -  person Carlos Isidoro López    schedule 16.12.2019
comment
Я бы сказал: опубликуйте подпись, которую вы пытаетесь проверить, открытый текст и опубликуйте ключ, который вы используете для проверки. На самом деле, мне кажется весьма вероятным, что (1) подпись закодирована в base64 (т.е. вам нужно будет запустить ее через base64_decode и (2) что Google использует заполнение PKCS1, тогда как phpseclib по умолчанию использует заполнение PSS для подписей. Вы можно изменить заполнение подписи на PKCS1, выполнив $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);   -  person neubert    schedule 16.12.2019
comment
@neubert Кажется, у тебя получилось, спасибо! Если вы опубликуете это как ответ, я могу принять это.   -  person Carlos Isidoro López    schedule 16.12.2019


Ответы (1)


Я бы сказал: опубликуйте подпись, которую вы пытаетесь проверить, открытый текст и опубликуйте ключ, который вы используете для проверки. На самом деле, мне кажется весьма вероятным, что (1) подпись закодирована в base64 (т.е. вам нужно будет запустить ее через base64_decode и (2) что Google использует заполнение PKCS1, тогда как phpseclib по умолчанию использует заполнение PSS для подписей. Вы можно изменить заполнение подписи на PKCS1, выполнив $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);

person neubert    schedule 16.12.2019