苹果的应用内购凭证校验步骤见官网:苹果app内购凭证校验,苹果的凭证验证有两种:
- Validating Receipts With the App Store 通过访问苹果接口进行验证。
- Validating Receipts Locally 本地代码解码进行验证
可以参考一个第三方应用内购库RMStore,这个库帮你省去了很多内购接入的麻烦。
其中第二种验证方式存在被破解的风险,因为这种验证是本地进行的,破解者可以通过伪造凭证进行破解,甚至通过一些内购破解插件来破解,所以安全考虑第一种方式是必须的,第二种验证可以同时存在(先进行本地,再请求服务器验证)。
1.这样就安全了吗?
一般还需要苹果的付款订单和我们自己后台的订单进行一对一约束,一次付款只能成功一次后台订单,这个需要自己后台人员去做限制,一对多和多对一都是不正确的。
2.用户付款成功了,但是苹果服务器校验失败了怎么办?
验证过程中如果由于网络问题失败或者苹果服务异常等原因导致验证失败,比如返回的报文格式不是json格式,则需要提供重试功能给用户重试,或者将凭证保存到后台,后台人员通过第一种方式重新验证。
3.漏洞
由于个人经验不足,对苹果校验的安全性没有太过关注,以致于作弊者破解了我们的苹果内购;我已经被这个折腾了一个月[抓狂],作弊者通过很多方式跳过苹果的付款步骤直接获得虚拟产品,达到免费获取虚拟产品的目的。
其中最让人胆寒的方式就是:作弊者可以自主伪造一个苹果凭证并且通过了苹果的服务器验证。
4.Oh my God,那应该如何修补这个漏洞?
对于这种伪造的凭证,虽然能通过苹果校验,也就是说返回的json的状态是成功的状态(state=0),但是仔细察看会发现数据是有缺失的,我们注意到返回的json报文都会有in_app节点,这个节点是一个数组,数组里包含字典,而这个字典一般会记录本次充值的相关信息,比如充值的产品id,充值的trasaction_id,正常的凭证校验返回的in_app节点是有数据的,而伪造的凭证校验返回的json中in_app节点是空的,我们可以根据这个判定是否是非法凭证。
这可能是苹果凭证校验的一个漏洞,而作弊者恰恰利用了这个漏洞。
如果想知道苹果内购返回的josn格式,请前往官文档。
最后总结一句:天外有天,人外有人,与天斗,其乐无穷:与地斗,其乐无穷;与人斗,其乐无穷,与黑客斗其乐无穷。