Проверка покупки Android InApp

У меня есть мобильное приложение с некоторыми встроенными элементами, которые пользователи могут покупать. Как только пользователи покупают какой-либо продукт inapp, приложение отправляет квитанцию ​​JSON на мой сервер для онлайн-проверки с использованием открытого ключа разработчика Google (хранящегося на сервере).

Приложение отправляет на сервер подпись и данные (также называемые квитанцией):

$signature = 'E2dxlmSe0d45eJpN4FKSUxNPYXM5A1zohpVL60Hd+5jd43j4YMhBlVRLwFeDaBKZnkJ39rYYesWoOu8Z5ysczAIiQO7Myko7UJYVYKvB5GqM8a0iEDjCdCpSRSqLUmaEHKwUJFfjcgw1K5L2gM/m3u8l7Jy25IB+HFVIikO50jiy8SMRh7S+s6PgEAXqG6K6vTpuTC5ECweuQ45VTdb0jNyWOzEW/I1nA5fAB/mmp5j3B6k7nN81NMh/3oUJHba/wWGlbkWtItmDU6/jMdpd1CVViNBhKe0ktwnSRz3XF607/AfZM6JteOKhC6TquWhVNuWpKJWdJbP7Q+RVS0YKog==';

$data = '{"orderId":"GPA.xxxx-xxxx-xxxx-xxxxx","packageName":"xxx.xxx.xxx","productId":"xxx","purchaseTime":1508881024560,"purchaseState":0,"purchaseToken":"didpmjkaldaddakgfabdohdj.AO-J1Ozqb8hZAa-_FLd-sQJgXhwruU3tVEYU0sqhlgXHb8I9wI35xDeQFgFI0Zpoaurw4Ry7zahymvge1U0WlEqqvvAKvwAo0Wk1MtawzAiqVdy2RTvwFGo"}';

Вот код PHP, который я использую для проверки подписи:

$pkey = "...";
$apkey = "-----BEGIN PUBLIC KEY-----\n".chunk_split($pkey, 64, "\n")."-----END PUBLIC KEY-----";
$pubkeyid = openssl_get_publickey($apkey);
$ok = openssl_verify($data, $signature, $pubkeyid);
openssl_free_key($pubkeyid);
echo $ok;

и конечно не работает. Функция OpenSSL возвращает 0 (вместо 1 для OK). Согласно онлайн-документации https://developer.android.com/google/play/billing/billing_integrate.html мне нужно проверить INAPP_PURCHASE_DATA, то есть receipt. Вот пример из документа:

'{
   "orderId":"GPA.1234-5678-9012-34567",
   "packageName":"com.example.app",
   "productId":"exampleSku",
   "purchaseTime":1345678900000,
   "purchaseState":0,
   "developerPayload":"bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ",
   "purchaseToken":"opaque-token-up-to-1000-characters"
 }'

Это именно то, что отправляет мое приложение. Теперь, когда для проверки подписи требуются данные с точностью до бита, как я должен «послать» такую ​​строку в функцию OpenSSL? В документе данные имеют разрывы строк и отступы, у меня та же самая структура JSON, но записанная как простая строка без разрывов строк и отступов. Это те же данные в формате JSON, но они сильно отличаются с точки зрения проверки криптографической подписи. Может кто-нибудь объяснить, как это сделать?


person Gianluca Ghettini    schedule 24.10.2017    source источник


Ответы (1)


Решил вопрос:

  • data должен быть простой строкой без отступов и разрывов строк.
  • подпись должна быть декодирована base64 перед передачей в функцию OpenSSL

Итак, вместо этого:

$ok = openssl_verify($data, $signature, $pubkeyid);

Я должен сделать это:

$ok = openssl_verify($data, base64_decode($signature), $pubkeyid);
person Gianluca Ghettini    schedule 25.10.2017