2015-07-10 166 views
1

我正在开发一款使用应用内购买的Android应用。用户购买后,Play商店将响应作为JSON字符串发送。这种反应看起来是这样的(无删节敏感信息,当然):Google Play结算响应签名验证

{ 
    "type":"android-playstore", 
    "id":"<My Application ID>", 
    "purchaseToken":"<The Purchase Token>", 
    "receipt":{ 
     "orderId":"<The Order ID>", 
     "packageName":"com.example.skeleton", 
     "productId":"credit.basic", 
     "purchaseTime":1436546971245, 
     "purchaseState":0, 
     "purchaseToken":"<The Purchase Token>" 
    }, 
    "signature":"Im27prAnxYwdRoug..." 
} 

Google Play billing security documentation指出

谷歌播放的迹象表明,包含采购订单的响应数据的JSON字符串。 Google Play会在开发者控制台中使用与您的应用关联的私钥来创建此签名。

我不是加密是不错,但我的理解是,RSA签名作品以字符串的SHA1哈希值进行签名,然后加密与私钥生成一个签名。当想要验证字符串的起源时,签名用公钥解密(证明它是用私钥加密的),并且将解密后的哈希与消息的哈希进行比较以查看它们是否匹配。

但是,这里有一个问题。签名本身包含在发送给我的应用程序的JSON字符串中。在签名后你不能更改字符串,所以当Google说他们“签署包含响应数据的JSON字符串”时,它们并不意味着我收到的整个JSON字符串。他们必须对字符串的一部分进行签名并将签名添加到该字符串中。我的问题是,我无法弄清楚字符串的哪一部分被签名。使用this question中描述的签名验证实现,我尝试验证删除了签名属性的JSON字符串,没有括号,只有收据部分等。为了好的措施,我尝试了整个字符串,包括签名。我似乎无法找到此JSON字符串的任何部分,可以用我的公钥进行加密验证。有没有我应该使用的字符串的一部分,或者我不明白签名是如何工作的?

回答

0

而且经常发生,在StackOverflow发布的30分钟内,我找到了答案。

问题源于我在PhoneGap中开发此应用程序并使用in-app-purchasing plugin执行此事务。当插件向我提供上面的JSON字符串时,该插件稍微对我说谎。 Google会在一个JSON字符串中发送响应数据,并在另一个JSON字符串中发送签名,而插件会将其封装到上面的单个字符串中。正确的方法是验证'收货'项目,如下所示。

{ 
     "orderId":"<The Order ID>", 
     "packageName":"com.example.skeleton", 
     "productId":"credit.basic", 
     "purchaseTime":1436546971245, 
     "purchaseState":0, 
     "purchaseToken":"<The Purchase Token>" 
} 

问题中列出的python实现验证此JSON字符串的签名。