Android InApp购买验证

时间:2017-10-24 22:01:32

标签: php android mobile in-app-purchase digital-signature

我有一个移动应用,其中包含一些用户可以购买的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。这里是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"
 }'

这正是我的应用发送的内容。现在,由于签名验证需要比特完美的数据,我应该如何发送"发送"这样的字符串到OpenSSL函数?在doc上,数据有换行符和缩进,mine是完全相同的JSON结构,但是记录为没有换行符或缩进的纯字符串。它与JSON方面的数据相同,但与加密签名验证的观点非常不同。有人可以解释一下怎么做吗?

1 个答案:

答案 0 :(得分:1)

解决了这个问题:

  • data必须是一个没有缩进或换行的普通字符串
  • 签名在传递给OpenSSL函数之前必须进行base64解码

所以不要这样:

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

我必须这样做:

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