本文转载至 http://blog.devtang.com/2013/04/07/tricks-in-iap/

前言

udacity 中的在线课程 《How to build a startup》 中提到,所谓创业,就是尝试寻找新的赢利模式。正因为这是一种尝试,所以不可避免地需要调整产品方向,寻找市场中还未被发现的用户需求,给用户创造价值,进而获得收入。最近很火的 精益创业 的观点,则是强调将这种尝试成本降到最小,使得自己可以根据市场反馈迅速调整产品。

我们在今年春节后上线了新的在线智能题库:猿题库。这应该是我们在互联网教育这个创业领域尝试的第二个方向。

猿题库现在推出了公务员考试行测和申论 2 个产品,均包括 web, iOS 和 Android 三个平台。这次我们尝试做一个收费的产品,所以在 iOS 端集成了应用内支付(IAP)功能。在开发过程中和上线后,我们遇到了 IAP 中的一些坑,在此分享给各位。

IAP 审核相关的坑

IAP 开发的详细步骤我写在 另一篇博客 中了。在此主要介绍审核时遇到的问题。

IAP 类型错误

由于我们是按月付费的产品,所以在设置 IAP 类型时,我没有经验,只是简单设置成了可重复消费 (Consumable) 的 IAP 项目。但是我不知道,苹果对于这种按时间收费的产品,应该使用不可更新的定阅(Non-Renewing Subscription)类型。这个类型设置错误造成了我们 app 的一次审核被拒。

IAP 验证逻辑

由于苹果在 iOS5.0 以下有 IAP 的 bug,使得攻击者可以伪造支付成功的凭证。而 iOS6.0 的系统在越狱后同样可以伪造凭证,所以我们对于应用内支付,增加了服务器端的验证。
服务器端会将支付凭证发给苹果的服务器进行二次验证,以保证凭证是真实有效的。

在我们公司的测试服务器中,我们会连接苹果的测试服务器(https://sandbox.itunes.apple.com/verifyReceipt )验证。

在我们部署在线上的正式服务器中,我们会连接苹果的正式服务器(https://buy.itunes.apple.com/verifyReceipt )验证。

我们提交给苹果审核的是正式版,我们以为苹果审核时,我们应该连接苹果的线上验证服务器来验证购买凭证。结果我理解错了,苹果在审核 App 时,只会在 sandbox 环境购买,其产生的购买凭证,也只能连接苹果的测试验证服务器。但是审核的 app 又是连接的我们的线上服务器。所以我们这边的服务器无法验证通过 IAP 购买,造成我们 app 的又一次审核被拒。

解决方法是判断苹果正式验证服务器的返回 code,如果是 21007,则再一次连接测试服务器进行验证即可。苹果的 这一篇文档 上有对返回的 code 的详细说明。

IAP 上线后的遇到的情况

我们在服务器端增加了验证 IAP 是否有效的逻辑。在产品上线后,如我们所料,我们收到了大量的欺骗性购买,这些都被我们的服务器识别出来了,但是我们也遇到了以下这次没有想到的情况:

1、由于国内越狱用户的比例比较大 (2012 年底国内越狱比例是 42%), 所以虽然我们服务器会验证购买凭证,但是每天有超过 50% 以上的凭证都是伪造的。同时由于苹果的验证服务器在美国,凭证验证请求响应的时间比较慢,大量的伪造凭证发给苹果服务器,不知道会不会被苹果认为我们是在恶意进行 DDOS。至少我们发现有些时候,验证请求会超时。

2、由于国内有许多小白用户,他们的手机从购买时就被渠道商帮忙越狱过了并且安装了 IAP free 插件。所以对于这类用户,他们即使想付费购买,由于系统原有的 IAP 支付功能已经被破坏,所以他们是无法正常付费的。麻烦的是,他们会以为这是我们的 app 的问题,转而给我们的客服打电话投诉。这让我们非常郁闷。

3、苹果的验证服务器有时候会出问题,我们发现本来约定好返回的 JSON 数据在有几次返回的居然是一个 XML 格式的文件。造成我们将正常的付费 IAP 凭证验证失败。所以,在服务器记录下所有的验证凭证非常有必要,一来可以防止黑客多次提交同一个成功凭证的重放攻击,二来在需要时可以手工进行再验证。

越狱手机可能被黑客窃取购买凭证!!

我们发现有一部分用户反馈说已经收到苹果的扣费账单,但是我们从服务器的验证记录看,他上传的凭证却是虚假的。由于这些用户不太多,我们一开始以为是用户在恶意欺骗我们,后来我们让他将苹果的付费账单邮件转发给我们,以及将 itunes 的购买记录截图转发给我们,随着讨论的深入,我们越来越怀疑这里面有一个黑色的产业链。越狱手机的正常购买凭证可能被黑客的恶意程序截获,具体的攻击方式我们讨论了一下,其实就是被 中间人攻击,详细的过程如下:

  1. 越狱手机的在被破解后,可能从一些破解渠道安装了黑客的恶意程序。
  2. 黑客将越狱手机所有 https 请求都经过他的中间服务器。
  3. 当有支付请求时,黑客先将请求发给苹果服务器,待苹果将成功的凭证返回后,黑客将这个凭证替换成假的凭证,完全支付凭证的偷取。

或许有人会问,这个凭证拿来有什么用呢 ? 很简单 ,因为苹果为了保护用户的隐私,支付凭证中并不包含任何用户的 apple id 信息,所以我们的 app 和服务器无法知道这个凭证是谁买的,而只能知道这个凭证是真的还是假的。于是黑客就可以用这个凭证,在另外的账号中通知我们完成了购买,而发来的验证凭证又是真实的,所以我们的服务器就会误认为是黑客的账号完成了购买,继而把会员期算在黑客的账号上。

再举一个简单的例子,你拿 500 块钱买了顺风优选的 500 元购物券,由于这个购物券是不记名的,所以顺风优选无法知道是谁买的。如果这个购物券在发放过程中被人掉包,那么偷购物券的人就可以拿这个偷来的真购物券来购物,而顺风优选的卡因为是不记名的,所以也无法查证这件事情。在这个例子中,购物券的不记名和苹果的支付凭证无账号信息是同一个道理。

鉴于以上情况,考虑到越狱手机不但不能成功支付,还会有安全问题,所以我们在新版中取消了越狱手机中的 IAP 支付功能。

所以,请大家还是不要越狱自己的手机,iPhone 手机越狱后风险相当大。实在不值得为了免费玩几个游戏就丢掉安全性。

后记

中间人攻击的演示

iOS 独立开发者 王轲 _IndieBros 在他的博客文章 《使用 mitmproxy 获取 iTunes 11 的 Raw HTTPs Response》 中演示了如何使用中间人攻击来修改 Game Center 游戏数据。王轲还把我的例子白话翻译了一下(可见我还是说得太绕了,囧):

坏人在购买过程中插了一腿,换走了用户的无记名发票(购物小票形象些),然后手持无记名小票伪装成真实顾客或者转手出售获利。

关于越狱与盗版

不少细心的同学评论纠正我,指出越狱并不等同于使用盗版。确实,如果说严格的定义,越狱只是让 iPhone 获得 root 权限,进而可以做任何事情。如果越狱的同学在越狱后不安装 IAP free 插件,不使用 app sync 插件,不使用任何国内的和非 bigboss 的 cydia 源,不使用任何盗版软件,所有应用都是从 app store 官方网站上下载的话,被黑客攻击的可能性会降低一些。

即使这样,由于手机已经被 root 了,苹果的沙盒安全机制失效,所以风险还是很大的。

关于越狱用户的比例

有同学提出我文章中写的越狱手机比例太高了,想询问数据来源。这个比例主要来自我们自己的 app 的统计信息,以及结合国内的统计工具友盟的 越狱手机比例统计,去年底国内的越狱比例是 42%。

iOS应用内支付(IAP)的那些坑的更多相关文章

  1. IOS应用内支付IAP从零开始详解

    前言 什么是IAP,即in-app-purchase 这几天一直在搞ios的应用内购,查了很多博客,发现几乎没有一篇博客可以完整的概括出所有的点,为了防止大伙多次查阅资料,所以写了这一篇博客,希望大家 ...

  2. Cocos2dx使用ios内支付IAP具体流程-白白

    今天总结了一下cocos2d-x使用ios内支付iap的具体流程,封装好了调用接口,代码与具体说明在此 http://download.csdn.net/detail/u010229677/81566 ...

  3. Cocos2d-x使用iOS游戏内付费IAP(C++篇)

    本文章转载 http://www.ityran.com/archives/5515.非本人原创! 前期准备 设备与账号 在开始编码之前我们需要准备测试环境. IAP只能真机测试,准备一台iOS设备是必 ...

  4. iOS应用内付费(IAP)开发步骤列表

    iOS应用内付费(IAP)开发步骤列表 前两天和服务端同事一起,完成了应用内付费(以下简称IAP, In app purchase)的开发工作.步骤繁多,在此把开发步骤列表整理如下.因为只是步骤列表, ...

  5. iOS应用内付费(IAP)开发步骤

    1.苹果iTunes Connect内购产品信息录入. 1)创建app内购买项目(Create New),选择类型: 1.消耗型项目 对于消耗型 App 内购买项目,用户每次下载时都必须进行购买.一次 ...

  6. iOS应用内支付(内购)的个人开发过程及坑!

    本文会给大家详细介绍iOS内购,这是本人16年5月底的开发过程,希望对看完此篇文章的人有所帮助. 本文基于XcodeVersion 7.3 (7D175)版本,手机是iPhone 6,9.3系统. 部 ...

  7. IOS IAP APP内支付 Java服务端代码

    IOS IAP APP内支付 Java服务端代码   场景:作为后台需要为app提供服务,在ios中,app内进行支付购买时需要进行二次验证. 基础:可以参考上一篇转载的博文In-App Purcha ...

  8. <转>iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!

    原文地址:http://blog.csdn.net/xiaominghimi/article/details/6937097 //——2012-12-11日更新   获取"产品付费数量等于0 ...

  9. 【转】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程

    http://blog.csdn.net/xiaominghimi/article/details/6937097 //——2012-12-11日更新   获取"产品付费数量等于0这个问题& ...

随机推荐

  1. C语言课程设计-保安值班系统支持任意输入保安值班时间

    //.cpp : Defines the entry point for the console application. // #include "string.h" #incl ...

  2. python3 实现mysql数据库连接池

    首先声明一下,这篇博客进行了通过自己的代码方式,加上这篇博客,最后总结出这段代码.参考博客连接:http://blog.csdn.net/zbc1090549839/article/details/5 ...

  3. SAP 产品条码WMS结合 以及ABAP script的集成 BarCode

    条码和RFID打印解决方案   1, 热转印条码标签打印 热转打印技术的原理是通过加温和加压将色带上的固体油墨熔化转印到介质上完成打印的.通过选择热转印色带与标签材料匹配,热转印打印方式可以产生耐高温 ...

  4. vscode 自定义快捷键

    vscode 自定义快捷键 这两天用vscode写了下Python,感觉很舒服,只是快捷键不如人意,略作修改,放上来作为备份.smile~ 主要更改: 代码格式化 ctrl+alt+l 执行代码 ct ...

  5. 嵌入式开发之makefile---交叉编译静态库和动态库的生成和调用

    c和cpp 混合的动态库生成: $(LIBSO): $(COBJS) $(CPPOBJS) $(CPP) -shared -o $@ $^ $(LIBS) ////////////////////// ...

  6. int[,] 和 int[][] 有什么区别

    int[,] 是二维数组,它就是传统意义上 n x m 的表,和 C++ 里的 int[][] 是一个意思. int[][] 是交错数组,与 C++ 里的 int[][] 不同.它其实是一个 int[ ...

  7. Intellij MyBatisPlus Plugin插件破解

    1. 下载原始的MyBatisPlus Plugin插件. 2. 下载替换包,请根据实际版本下载: https://github.com/myoss/profile/tree/master/idea/ ...

  8. 7款HTML5精美应用教程 让你立即爱上HTML5

    你喜欢HTML5吗?我想下面的这7个HTML5应用一定会让你爱上HTML5的,不信就一起来看看吧. 1.HTML5/jQuery雷达动画图表 图表配置十分简单 之前我们介绍过不少形形色色的HTML5图 ...

  9. JAVA的get post 区别

    1. get 是从服务器上获取数据,post 是向服务器传送数据. get 请求返回 request - URI 所指出的任意信息.Post 请求用来发送电子邮件.新闻或发送能由交互用户填写的表格.这 ...

  10. 设计模式1-单例模式(Singletion)

    单例模式(Singletion):保证一个类仅有一个实例,并提供一个访问该实例的全局访问点. 单例模式主要作用是保证唯一的实例,可以严格地控制客户端怎样访问该实例以及何时访问它.可以简单的理解为对唯一 ...