简体   繁体   中英

Android InApp purchase verification

I have a mobile app with some inapp items that users can purchase. Once users buy some inapp product the app sends the JSON receipt to my server for online verification against my Google developer public key (stored in the server).

The app sends signature and data (aka the receipt) to the server:

$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"}';

Here's the PHP code I'm using for signature verification:

$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;

and of course it doesn't work. The OpenSSL function returns 0 (instead of 1 for OK). According to the online documentation https://developer.android.com/google/play/billing/billing_integrate.html the thing I have to check is INAPP_PURCHASE_DATA which is receipt . Here an example from the doc:

'{
   "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"
 }'

Which is exactly what my app sends. Now, since signature verification requires bit perfect data, how I'm supposed to "send" such string to the OpenSSL function? On the doc the data has line breaks and indentation, mine is the very same JSON structure but recorded as a plain string without line breaks nor indentation. It's the same data JSON-wise but very different from a cryptographic signature verification point of view. Can someone please explain how to do it?

Solved the issue:

  • The data has to be a plain string with no indentation nor line breaks
  • signature has to be base64 decoded before passing it to the OpenSSL function

So instead of this:

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

I have to do this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM