1. 客户端直接verify苹果的receipt 如果verify成功 自行发放商品

2. 客户端将receipt传给server,由server进行验证并发放商品

按照安全性原则, 客户端的所有信息都是不可信的,而且支付是业务中的核心模块,所以应该选择第二种。

下面简要介绍下,第二种方式的简单流程。

1. 客户端支付成功,拿到receipt

2. 客户端将receipt传到服务端

3. 服务端去apple验证receipt 如果验证成功 就发放receipt中的商品

支付安全性

作为支付,安全性是第一位的,下面简要分析一下常用的攻击手段。

1、劫持apple server攻击 => 通过dns污染,让客户端支付走到假的apple_server,并返回验证成功的response。 这个主要针对支付方式一 如果是支付方式二 就无效。

2、重复验证攻击 => 一个receipt重复使用多次

3、跨app攻击 => 别的app的receipt用到我们app中来

4、换价格攻击 => 低价商品代替高价商品

5、歧义攻击 => iap支付之前的status=0表示verify成功 而现在变为status=0只能表示receipt合法 具体支付详情需要通过in_app字段决定 For iOS 6 style transaction receipts, the status code reflects the status of the specific transaction’s receipt.

6、中间人攻击 => 伪造apple_server,如果用户支付就将

劫持apple server攻击

通过dns污染,让客户端通过假的apple_server进行verify,从而认为自己支付成功。这个主要针对**支付方式一**,如果是支付方式二,就没效果了。常见的iap hack软件@iAPFree @iAP Cracker 就是用的类似原理。

重复验证攻击

因为同一个receipt,如果第一次验证成功,那么之后每次验证都会成功。如果服务端没有判重机制,就会导致一个receipt被当做多次充值处理。

为了预防这种情况,我们可以将receipt做一次md5得到receipt_md5, 每次发送充值请求的时候就按照receipt_md5判重,如果重复就停止商品发放。

跨app攻击

通过在别的app中拿到receipt,然后发送到我们app中。因为这个receipt是合法的而且apple不会验证请求的源,所以这个receipt是可以验证通过的。

对于这种情况,我们可以判断apple verify的返回值apple_callback_data中对应的bundle_id和我们app的bundle_id是否一样来进行验证。

换价格攻击

在同一个app中,用低价商品的receipt伪造购买高价商品。这时候bundle_id和我们app的bundle_id是一致的。

针对这种情况, 我们可以从apple verify的返回值apple_callback_data中拿到对应的PRoduct_id, 并按照product_id来进行充值。 **不要信任客户端的product_id**

歧义攻击

在iOS6的时候,status=0表示此次支付成功,而现在变为status=0只表示receipt**整体上**合法。

所以,对iOS7即使是一个过期订单,也会返回status=0,如果还按照iOS6的逻辑处理,就会导致假充值。针对iOS7,我们应该不只通过status,还要通过in_app中的内容,来决定如何发放商品。

```

For iOS 6 style transaction receipts, the status code reflects the status of the specific transaction’s receipt.

For iOS 7 style app receipts, the status code is reflects the status of the app receipt as a whole. For example, if you send a valid app receipt that contains an expired subscription, the response is 0 because the receipt as a whole is valid.

中间人攻击

伪造apple server,将我们的支付请求转发到真的apple_server,拿到合法的receipt,并弄个假的receipt给客户端。这样就拿到一个合法的凭证。利用这个合法的receipt,伪造别人充值的请求,从而达到帮别人充值的目的。

针对中间人攻击,最重要的是保证a用户的支付receipt,不能被b用户使用。但是apple为了保护隐私,receipt中没有任何用户的个人信息,这就需要我们自己来保证。目前我们用加密的手段来做这个保证。

iOS支付的详细流程

客户端拿到apple的receipt 并发送到serverserver拿到这个receipt,向苹果验证得到apple_callback_data如果apple_callback_data的status是21007,说明是沙盒模式(不用花钱就可以购买) 要根据具体需求判断处理逻辑,需要注意的是,ios的审核在支付的时候就采用的沙盒模式。

如果apple_callback_data的status是0,就要从apple_callback_data[‘receipt’][‘in_app’]这个list中拿到所有的记录,每一个进行充值。然后记录transaction_id和original_transaction_id来防止同一个transaction被重复使用。

https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Restoring.html

https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW1 => Original Transaction Identifier

返回所有充值成功和重复的transaction_id, 有client来complete transaction

总结

支付作为核心模块,除了技术上的保证,商务也应该每周进行一次对账。如果发现apple上的收入和服务端记录的收入有比较大的差距,就应该抓紧查看原因。

最后给出一个apple_callback_data的例子

{

"status": 0,

"environment": "Production",

"receipt": {

"download_id": 75017873837267,

"adam_id": 1149703708,

"request_date": "2017-01-13 06:57:20 Etc/GMT",

"app_item_id": 1149703708,

"original_purchase_date_pst": "2016-11-17 18:57:09 America/Los_Angeles",

"version_external_identifier": 820252187,

"receipt_creation_date": "2017-01-13 05:04:52 Etc/GMT",

"in_app": [

{

"is_trial_period": "false",

"purchase_date_pst": "2017-01-12 21:04:52 America/Los_Angeles",

"original_purchase_date_pst": "2017-01-12 21:04:52 America/Los_Angeles",

"product_id": "com.lucky917.live.gold.1.555",

"original_transaction_id": "350000191094279",

"original_purchase_date": "2017-01-13 05:04:52 Etc/GMT",

"original_purchase_date_ms": "1484283892000",

"purchase_date": "2017-01-13 05:04:52 Etc/GMT",

"purchase_date_ms": "1484283892000",

"transaction_id": "350000191094279",

"quantity": "1"

}

],

"original_purchase_date_ms": "1479437829000",

"original_application_version": "26",

"original_purchase_date": "2016-11-18 02:57:09 Etc/GMT",

"request_date_ms": "1484290640800",

"bundle_id": "com.lucky917.ios.Live",

"receipt_creation_date_pst": "2017-01-12 21:04:52 America/Los_Angeles",

"application_version": "32",

"request_date_pst": "2017-01-12 22:57:20 America/Los_Angeles",

"receipt_creation_date_ms": "1484283892000",

"receipt_type": "Production"

}

}

iap java md5_苹果应用内支付(iOS IAP)的流程与常用攻击方式相关推荐

  1. 苹果应用内支付(iOS IAP)的流程与常用攻击方式

    苹果应用内支付(iOS IAP)的流程与常用攻击方式 Jan 19, 2017 常见支付流程 iap(in app purchase)指苹果应用内支付, 目前主要有两种方式. 1. 客户端直接veri ...

  2. 购买抖币显示苹果服务器异常,抖音刷礼物为什么显示当前设备不支持苹果应用内支付?...

    因为两者不关联,所以不支持苹果应用内支付. 抖音软件的支付和苹果内部支付没有关联好,可以换个支付方式,若用户已有可用帐户余额,首次使用苹果应用内购买DOU+币后,原帐户余额将合并为DOU+币计算.展示 ...

  3. [汇文教育]iOS内支付(IAP)研究

    关于iOS内支付(简称IAP,全称In App Purchase)的demo可以从以下链接下载:点击打开链接 一.实现支付功能的前提条件: 1.有一个可以发布产品的开发者账号,有一个可以运行应用的开发 ...

  4. uniapp 实现苹果应用内支付(可直接复制使用)

    先根据uniapp官方链接,按步骤实行(了解官方操作,方便出现BUG不懵逼,也可直接复制下方代码直接使用) 如果沙箱环境遇到疑问可以参考 根据uniapp官方demo并加以改正 ApplePay.js ...

  5. 服务器接收 App Store 苹果商店内购项目IAP的退款通知

    苹果商店内购IAP相信大家一定不陌生,苹果从中抽成30%更是让大多数公司都很反对.有时候碰上恶意退款的人更是没有办法,只能认栽.好消息是苹果终于上线了退款通知! "AppStore服务器通知 ...

  6. ios 自己服务器 苹果支付_iOS应用内支付(IAP)服务端端校验详解

    { "status": 0, "environment": "Sandbox", "receipt": { " ...

  7. 谈谈苹果应用内支付(IAP)的坑

    一.请求商品 下面是请求商品的代码: - (void)validateProductIdentifier:(NSArray *)productIdentifier {SKProductsRequest ...

  8. 苹果支付返回html,苹果应用内支付,服务器端的实现

    苹果支付的逻辑如下首先客户端先请求苹果支付中心,支付中心返回给客户端一堆加密的数据. 然后客户端把这段加密的数据 base64之后传给后端. 最后由后端再去请求苹果支付中心来验证这次购买是否成功.验证 ...

  9. iOS应用内支付(IAP)的那些坑

    我们在今年春节后上线了新的在线智能题库:猿题库.猿题库现在推出了公务员考试行测和申论2个产品,均包括web, iOS和Android三个平台.这次我们尝试做一个收费的产品,所以在iOS端集成了应用内支 ...

最新文章

  1. 记录一次nginx升级,支持ipv4和ipv6访问https
  2. 开发日记-20190529 关键词 读书笔记《鸟哥的Linux私房菜-基础学习篇》
  3. %@taglib prefix=c uri=http://java.sun.com/jsp/jst1/core%报错
  4. 工具 每分钟_black: 一个不妥协的Python代码格式化工具
  5. 什么是I帧,P帧,B帧
  6. Python+OpenCV:高动态范围(High Dynamic Range, HDR)
  7. MAC中让右键菜单出现终端(命令行)打开文件夹的功能
  8. 网上一好人收集的PDF制作软件大全
  9. 按键精灵不成熟的大漠游戏自动加血保护代码 大漠字库使用案例
  10. 安卓中的inflate方法
  11. 阿里二面一问MySQL就开始野了,抓着底层原理不撒手啊!
  12. 微信小程序云开发如何实现上传视频 以及 图片
  13. 禁止应用和adb安装APK
  14. 使用 docker 运行 drupal
  15. 第二次作业:支付宝案例分析
  16. Debian 修改系统语言
  17. Java基础入门第三版黑马课后习题(编程部分)
  18. Minio分布式存储入门(使用新版本)
  19. atrix 4g linux,多年耳烧发现atrix4g的内放音质非常好。对比多款主流手机
  20. Access denied for user root. Superuser privilege is required

热门文章

  1. 使用Grab的实验平台进行混沌实验编排
  2. 2018年最佳深度学习书单
  3. 到底是无线最难?还是核心网最难?
  4. ESL:我们如何使用首云混合云产品实现提效降本
  5. Mendix:低代码平台四大常见用例开发
  6. 震惊!程序员要放弃 Python 了!?发生了啥?
  7. AWS在深圳成立大中华区第二个物联网实验室
  8. linux系统无法识别固态硬盘_linux查看硬盘是不是ssd
  9. 火柴人_火柴人战争遗产修改无限金币钻石
  10. web 前端 如何分享到instagram_好程序员web前端教程分享前端javascript练习题三