【IAP支付之三】苹果IAP安全支付与防范 receipt收据验证

这里网上的朋友已经介绍的很详细了,具体的链接已经无法找到了。

这里主要说几点本人在开发中遇到的问题:

1.漏单必须要处理,玩家花RMB购买的东西却丢失了,是绝对不能容忍的。所谓的漏单就是玩家已经正常付费,却没有拿到该拿的道具。

解决:只要购买成功,便将购买记录(receipt等账单信息)保存下来,然后将账单信息传送给我们游戏服务器,游戏服务器获得账单后,和苹果服务器验证,账单有效的话,回馈给游戏服务器处理,游戏服务器处理后,返回给游戏客户端处理,处理完毕,将本地保存的购买记录删除。

2.漏单的检测位置

解决:

2.1 做法1:在任意购买成功之后,顺便检测一次漏单,有漏单数遍处理了。

2.2 做法2:是在游戏登陆的时候检测一次漏单,即循环检测漏单数据,挨个发送给服务器验证处理,直到将所有的漏单处理完毕。这是原因是购买服务器未返回结果而客户端崩溃的情况下,玩家再次登陆,会产生漏单。

3.漏单的版本兼容

漏单要做好版本兼容,eg.玩家购买英雄ID为100的英雄,产生了一次漏单,但是一直未再次登陆游戏,由于版权等原因,这个英雄在后期版本中被删除了,如果玩家这是漏单处理,会在服务器获得一个丢弃的英雄,产生数据异常。

我的处理是,如果是英雄,检测英雄在本地hero.csv中是否有效,如果有效,检测这个英雄是否已经拥有,如果没有且数据正常,发送给服务器处理漏单,否则丢弃掉这条漏单。

还有说苹果服务器漏单过期的说法,不过我没有遇到过,没做处理。

4.服务器和客户端漏单对应顺序

遇到过这种情况,客户端产生了多个漏单,发送给游戏服务器验证,游戏服务器请求苹果服务,苹果服务器返回的receipt的json数据中包含一个所有未处理的订单列表,最后产生的购买数据在最后,客户端的漏单顺序和服务器的验证顺序要保持一致。

NOTE: The validated receipt may contain multiple transactions in the “in_app” parameter. It seems that Apple keeps all of the user’s transactions in the receipt in chronological order. Assuming users can only
purchase one product at a time in your app, you want to grab the last transaction in the “in_app” array.

receipt的参数可以参考如下:

https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW1

向苹果服务器验证收据返回的数据:

Status Description
0 The receipt provided is valid.
21000 The App Store could not read the JSON object you provided.
21002 The data in the receipt-data property was malformed.
21003 The receipt could not be authenticated.
21004 The shared secret you provided does not match the shared secret on file for your account.Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.
21005 The receipt server is not currently available.
21006 This receipt is valid but the subscription has expired. When this status code is returned to your server, the receipt data is also decoded and returned as part of the response.Only returned for iOS 6 style transaction receipts for auto-renewable
subscriptions.
21007 This receipt is a sandbox receipt, but it was sent to the production server.
21008 This receipt is a production receipt, but it was sent to the sandbox server.

-------------------------------------------------------华丽丽的分割线-----------------------------------------------------------------------

这两天我在筹备我们的游戏APP的内购,仔细考虑了几个付费安全上的问题。凡是涉及到付费的问题都很敏感,任何一方出现损失都是不能接受的,所以在这里整理一些支付安全的要点分享一下。IAP是指In-App Purchase, 是一种付费方式,而并不是苹果专有的付费方式,在其它平台上也会有不同的实现,这里针对Apple IAP。

说到IAP安全问题,在苹果的IAP流程中有一个比较明显的逻辑漏洞,这个逻辑漏洞是建立在我们处理不当的情况下发生的,会导致己方提供的服务和玩家之间出现问题。先看看IAP支付时序图:

整个支付流程如下:

1.客户端向Appstore请求购买产品(假设产品信息已经取得),Appstore验证产品成功后,从用户的Apple账户余额中扣费。

2.Appstore向客户端返回一段receipt-data,里面记录了本次交易的证书和签名信息。

3.客户端向我们可以信任的游戏服务器提供receipt-data

4.游戏服务器对receipt-data进行一次base64编码

5.把编码后的receipt-data发往itunes.appstore进行验证

6.itunes.appstore返回验证结果给游戏服务器

7.游戏服务器对商品购买状态以及商品类型,向客户端发放相应的道具与推送数据更新通知

这七个步骤实际上是一个很安全的流程了。那问题出在哪里呢?我们谈谈两种苹果IAP的验证模型。

IAP built-in Model,本地验证

有些单机游戏甚至是网游,都直接跳过了3~7步骤,在第2步拿到receipt-data之后,直接由客户端向itunes.appstore发送验证请求,并且拿到结果,根据结果修改游戏数据。

我们在设计游戏的时候都遵循一个真理,“凡是在客户端的数据都是不安全的”,深以为然。如果没有独立服务器辅助验证,这样也就避免不了数据被修改的事实了,是的,你会少赚钱。不过如果网游也不通过独立服务器验证,而是在客户端验证之后再告知服务器状态让其发放游戏道具,那就太可怕了点。这是IAP built-in Model,经常出现安全问题的逻辑如下:

?


1

2

3

4

5

6

7

void

paymentQueue(...)

{

    if

(transaction != nullptr)

    {

        me.money
+=
1000;

    }

}

上面的代码在接收到付费成功的response就直接给游戏发放商品,不对产品和单据进行验证。如果receipt-data允许放在本地验证,就可能发生我们说的免费内购的BUG. 而实际上也真的有类似IAPCracker/IAPFree等工具专门利用这样的IAP漏洞的。而对于已经越狱了的iOS设备就太简单了,甚至不需要通过伪造或者跳过receipt-data验证就可以修改本地数据达到目的。

那是不是就完全不能让这个过程变得安全了呢?也不是,但这个安全保障只是让修改变得困难而已。苹果官方提供了 Validating Receipts Locally 在客户端对receipt-data进行安全验证,主要是对证书以及签名的合法性验证。如果不想自己写代码验证,也可以借助第三方机构提供的receipt-data验证API,比较著名的有  urbanairship和  beeblex 。

但如果能伪造一个完全合法的receipt-data,是不是一样可以达到欺骗目的。是的,为了绕过Validating Locally,于是黑客开始用自己伪造的receipt-data进行移花接木,所以出现了可以伪造”合法订单”的 in-appstore 。因此这种本地加强验证的方法也不能完全避免IAP攻击。

IAP Server Model,服务器验证

而如果我们把验证逻辑移到服务器上,这个过程就变得容易多了。因为不再需要担心receipt-data被伪造的问题。不过就算把步骤4~7在服务器上做了,同样也会产生一些幼稚的逻辑漏洞

对验证receipt-data的reponse content不进行验证和记录,只根据Product直接发放商品。这样只要客户端不断提交receipt-data,按照正常逻辑你就需要不断验证并且重复发放商品。较为安全的做法是:

在每一次收到receipt-data之后,都把提交的玩家账号以及receipt-data中的单号建立映射并记录下来,在每次验证receipt-data时,先判断其是否已经存在。

只要做了这样的验证,整个支付流程都变得明朗起来。

确保receipt-data的成功提交与异常处理

建立在IAP Server Model的基础上,并且我们知道手机网络是不稳定的,在付款成功后不能确保把receipt-data一定提交到服务器。如果出现了这样的情况,那就意味着玩家被appstore扣费了,却没收到服务器发放的道具。

解决这个问题的方法是在提交receipt-data的协议上设一个返回值,让服务端告知它已经成功收到并验证了receipt-data. 在没有收到这样的回复之前,客户端必须要把receipt-data保存好,并且定期向服务端发起请求,直至收到服务端的回复为止。这里就是我在开头提到的漏单处理了。

如果是客户端没成功提交receipt-data,那怎么办?就是玩家被扣费了,也收到appstore的消费收据了,却依然没收到游戏道具,于是投诉到游戏客服处。

这种情况在以往的经验中也会出现,常见的玩家和游戏运营商发生的纠纷。游戏客服向玩家索要游戏账号和appstore的收据单号,通过查询itunes-connect看是否确有这笔订单。如果订单存在,则要联系研发方去查询游戏服务器,看订单号与玩家名是否对应,并且是否已经被使用了,做这一点检查的目的是 为了防止恶意玩家利用已经使用过了的订单号进行欺骗
(已验证的账单是可以再次请求验证的,曾经为了测试,将账单手动发给服务器处理并成功),谎称自己没收到商品。这就是上面一节IAP Server Model中红字所提到的安全逻辑的目的。当然了,如果查不到这个订单号,就意味着这个订单确实还没使用过,手动给玩家补发商品即可。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-11 19:56:03

【IAP支付之三】苹果IAP安全支付与防范 receipt收据验证的相关文章

apicloud含有微信支付。支付宝支付和苹果内购的代码

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/> <meta name="

微信h5支付demo微信H5支付demo非微信浏览器支付demo微信wap支付

一.首先先确定H5支付权限已经申请!(需要微信h5支付demo的可以加 851 488 243 备注:h5支付) 二.开发流程 1.用户在商户侧完成下单,使用微信支付进行支付 2.由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB 3.统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名"mweb_url"),商户通过mweb_url调起微信支付中间页 4.中间页进行H5权限的校验,安全性检查(此处常见错误请见下文) 5.如支付成

支付宝支付开发—当面付条码支付和扫码支付

关键字:支付宝 当面付 条码支付 扫码支付 二维码支付 订单查询 退款作者:方倍工作室 本文介绍支付宝中当面付下属的条码支付.扫码支付.订单查询.退款申请的集成开发过程. 本文分为以下五个部分: 条码支付和扫码支付介绍 申请应用 密钥生成及配置 API及SDK集成 条码支付.扫码支付.订单查询.退款申请 一.条码支付及二维码支付介绍 1. 条码支付 条码支付是支付宝给到线下传统行业的一种收款方式.商家使用扫码枪等条码识别设备扫描用户支付宝钱包上的条码/二维码,完成收款.用户仅需出示付款码,所有收

【Java EE 学习 21 下】【 使用易宝支付接口实现java网上支付功能】

一.网上支付分为两种情况,一种方法是使用直接和银行的支付接口,另外一种方法是使用第三方支付平台和银行对接完成支付. 1.直接和银行对接. 2.使用第三方支付平台 3.常见的第三方支付平台 二.使用易宝支付接口实现java网上支付功能(农业银行). 1.完整源代码:https://github.com/kdyzm/day21_2_pay 2.实现过程的时序图 3.技术要点 (1)使用GET请求的时候必须将全部参数都带上,参数名称参考开发者文档中的请求参数列表 (2)使用PaymentUtil类实现

支付宝支付开发——当面付条码支付和扫码支付

关键字:支付宝 当面付 条码支付 扫码支付 二维码支付 订单查询 退款作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/alipay-f2fpay.html 本文介绍支付宝中当面付下属的条码支付.扫码支付.订单查询.退款申请的集成开发过程. 本文分为以下五个部分: 条码支付和扫码支付介绍 申请应用 密钥生成及配置 API及SDK集成 条码支付.扫码支付.订单查询.退款申请 注: 支付宝支付开发有一定的门槛,如果您愿意为知识付费来节省您宝贵的时间,请直接见底

微信支付--申请微信支付,商户功能设置详细说明

原文链接:http://www.cnblogs.com/True_to_me/p/3565039.html 微信支付已经正式开放了,所有的"认证服务号"都可以申请.但由于关系到支付权限的申请,整个流程会比较复杂,而且有很多具体的涉及技术接口的细节一般人还真弄不明白.而且已经有商户告诉我们发现有第三方网站在教商户申请微信时让不了解真相的商户把自己的微信支付直接就绑定了第三方网站的支付接口,给商户带来了很大的麻烦.非常的不负责任.大家一定要仔细阅读下面的内容,以免绑定后才发现是绑定了别人的

微信支付id出现的重复支付解决方法和app应用中多种支付方式之间的对比

1.微信支付的transId发起支付请求,未登录微信,先帐号登陆,否则直接去支付.这样的话,该transId跟该帐号绑定起来了, 如果下一次再重新使用该transId来支付请求,但是想切换其他的微信帐号来支付的话,微信就会提示报错信息. 2.所以解决的方法就是每次发起支付请求的时候,transId都是不同的,暂且定义为transId尾号递增1,所以每次进来都是不同的transId,这样就算切换帐号也不会报错. 3.但是根据2的修改方法,在实际的线上运营中,确实有人出现微信多次重复支付的情况,一笔

“流支付”掀起互联网支付创新浪潮,SAK支付白皮书揭秘

比特币,一个互联网技术与货币发行相结合的产物,带给我们区块链技术和DAC(Distributed Autonomous Corporation分布式自治系统)思想.鲨鱼币(简称SAK)的诞生是基于比特币的技术原理,并在支付上更便捷丶更快速,交易的确认时间由比特币的10分钟左右缩短到20秒左右. 自比特币诞生以来,加密货币在全球形成了蓬勃发展的趋势.加密货币的生产丶交易丶支付丶兑换四个环节在技术上形成了完整的支持,为加密货币的应用提供了良好的技术基础.但是对于加密货币的发展定位,还没有一个明确的方

美国会议签证——我是正当理由去美国,我能支付(或有人为我支付)我在美国期间的所有费用,办完事我肯定回来, 邀请信,行程表这些材料齐全即可

急!有去美国参加会议签证经验的请进啊~~~~ hiki 来自签证版问题 5月从英国想去参加个会议,因为以前被拒过,这次特紧张 签过的xdjm能分享下经验嘛?除了网站上要的材料,还需要别的嘛? 谢谢大家了 7 sweetsong 准备好使馆要求的材料,还有你认为所有能证明你和现在居住国有strong tie的东西,比如工作证明什么的,interview的时候自信一点,给签证官那种"我是正当理由去美国,我能支付(或有人为我支付)我在美国期间的所有费用,办完事我肯定会来"这种印象就好了~~~