我的服务器如何安全地验证iPhone应用内购买?

jef*_*091 23 iphone authentication certificate in-app-purchase iphone-sdk-3.0

查看Apple的服务器购买模型图.

在步骤#9中,服务器如何知道它实际上正在与有权购买的iPhone通话,并且Eve没有使用不诚实获得的收据进行重播?

收据可能有效,但不能证明发件人是授权方.

iPhone上是否有可用于签署收据的设备证书?

有没有办法将收据绑定到设备,或将收据绑定到iTunes帐户和设备,以便服务器可以验证?

Ben*_*n S 33

Apple提供的易受攻击的方法

服务器可以通过执行以下操作来验证购买:

  1. iPhone应用程序transactionReceipt在购买后收到.让iPhone base64对其进行编码(您可以将此开源添加到NSData中)并将其发送到您的服务器.(您甚至可以按原样发送它,并让服务器base64在验证之前对其进行编码.)

  2. 让你的服务器发送与单个键JSON请求receipt-data与编码的base64 transactionReceipthttps://buy.itunes.apple.com/verifyReceipt使用HTTP POST.(有关如何使用各种服务器端语言执行此操作的说明,请参阅此站点)

  3. 服务器将使用带有两个键的JSON对象进行响应:status这是一个整数,receipt并且是重复的收据.

如果status为零,则应接受收据有效,非零值表示收据无效.

安全加入Apple的方法

但是,存在一些安全隐患.用户可以使用其他用户的收据,因为设备不与收据绑定,或者用户可以使用其他产品的收据,因为服务器不验证收据的产品ID.为确保不会发生这种情况,您还应执行以下操作:

  1. 当您第一次收到应用程序中的收据时,立即通过安全通道(如HTTPS或SSL套接字)将其与设备的UUID一起发送到您的服务器.不要将它存放在任何地方,留在内存中.

  2. 在服务器上,将UUID和收据对存储在数据库中.

  3. 当设备发送UUID和收据对时,请向您的数据库确认收据尚未使用,通过检查收据的产品ID确保收据实际上是您的产品.收据只是一个JSON对象,因此您的服务器可以通过解码来自base64的收据来读取内容.

  4. 通过安全通道向设备返回响应,告知其购买是否:

    • 认证为新的(不在DB中并且有效)
    • 过去验证(相同的UUID和收据对已在DB中)
    • 由于错误的产品ID而被拒绝
    • 由于已经将收据与另一个UUID一起使用而被拒绝.

由于收据仅存储在设备的内存中,并且您的应用程序使用设备的UUID(可能被越狱设备欺骗,请参阅注释),并且所有购买的产品都以安全的方式使用设备的UUID记录在服务器上; 用户无法使用其他用户的收据来验证购买,也无法使用其他产品的收据,因为您检查了该收据.

如果要验证交易的其他详细信息,还可以验证收据中的其他字段.例如,如果您的产品是订阅,那么您也希望查看交易日期.

此外,用户不能假装是您的服务器,因为他们没有您的SSL证书,因此将设备置于具有与您相同名称的主机的专用网络上.

失败考虑因素

由于在用户的设备收到收据并使用您的服务器进行验证之间可能会发生故障(例如,如果用户失去连接,或者您的服务器因维护而关闭),您也应该让用户"重新授权".重新授权应该从商店获得收据(使用恢复的交易)并将其重新发送到服务器,就像这是一个新的购买.这应该很少需要使用,但应该可以保存用户在网络出现故障时不得不重新购买产品.

多设备考虑因素

这意味着如果用户想要在多个设备上使用应用程序,他们将不得不多次购买该产品.这可能是期望的效果,但您可能应该在购买之前通知用户,因为他们可能希望能够使用与其帐户关联的设备中的内容.

如果收据还包含iTunes帐户信息,则身份验证可以使用该信息允许用户在其所有设备(但不是他们的朋友)之间共享内容.

  • 我不确定我是否理解了您正确使用设备的UUID的方法.我的理解是,您可以在多个设备上安装应用程序而无需额外费用.将应用程序限制为设备UUID也意味着如果您升级/更换手机,则需要再次购买所有应用程序. (4认同)
  • 可以使用越狱设备欺骗UDID.作为服务器,您不知道移动设备上实际运行的代码.它可以为UDID值发送任何想要的东西. (3认同)
  • @kristof:你是对的,但这是安全验证收据的唯一方法,因为它不会被欺骗.如果Apple在收据中包含iTunes帐户,或者有一种安全的方法可以验证给定设备UUID是否与另一台设备相关联,则可以安全地验证与给定iTunes帐户关联的所有设备的购买情况,事实并非如此.也许在将来的更新中,这将是可用的. (2认同)