防止重放攻击 appStoreReceiptURL 应用收据

Dan*_*ich 5 app-store storekit ios receipt-validation

我们有一项服务器端服务,我们只想向付费 iOS 应用程序的有效用户提供该服务。(请注意,这是付费的 iOS 应用程序,而不是带有 IAP 的免费应用程序。)

当我们appStoreReceiptURL用来检查沙盒应用收据并将其发送到我们的服务器端时,我们会看到这样的收据:

{
  "receipt_type": "ProductionSandbox",
  "adam_id": 0,
  "app_item_id": 0,
  "bundle_id": "com.example.myapp",
  "application_version": "1.1.1",
  "download_id": 0,
  "version_external_identifier": 0,
  "receipt_creation_date": "2018-04-16 23:53:58 Etc/GMT",
  "receipt_creation_date_ms": "1523922838000",
  "receipt_creation_date_pst": "2018-04-16 16:53:58 America/Los_Angeles",
  "request_date": "2018-04-17 03:25:42 Etc/GMT",
  "request_date_ms": "1523935542798",
  "request_date_pst": "2018-04-16 20:25:42 America/Los_Angeles",
  "original_purchase_date": "2013-08-01 07:00:00 Etc/GMT",
  "original_purchase_date_ms": "1375340400000",
  "original_purchase_date_pst": "2013-08-01 00:00:00 America/Los_Angeles",
  "original_application_version": "1.0",
  "in_app": []
}
Run Code Online (Sandbox Code Playgroud)

我担心此收据的重放攻击。在重放攻击中,一个设备购买了应用程序并提交了有效收据,但另一台未经授权的设备存储并传输了第一个收据的精确副本。由于第一张收据由 Apple 签署,因此副本似乎有效。

理想情况下,我们会通过观察收据中的唯一标识符来击败重放攻击;如果有人试图重新传输相同的收据 ID,我们就会知道它是重复的。transaction_identifier正是出于这个原因,IAP 收据包含一个字段。

但似乎没有唯一标识符可用于识别付费应用收据的重放攻击。黑客可以从不同的设备向我们重新传输此收据,我们将无法知道它是复制的收据还是新的原始收据。

话虽如此,我的眼睛被吸引到那些_id在沙箱中收到的0号:adam_idapp_item_id,和download_id。我们可以使用其中任何一个来识别重复收据吗?或者有没有其他更好的方法来处理这个问题?

Dan*_*ich 1

无法检测付费应用程序的重复收据。、和没有记录,因此开发人员不能依赖它们来实现安全目的adam_id。这与 IAP 收据不同,后者包含可进行重复数据删除的收据。app_item_iddownload_idtransaction_identifier

不过,有一个可能的解决方法。您可以向用户提供 0 美元(免费)的非消耗性 IAP,并要求用户“购买”它才能访问服务器端功能。由于它是非消耗性 IAP,因此每个付费应用用户最多只能购买一次。

对于用户来说,同意免费“购买”并登录 App Store 来访问它有点麻烦,但一旦他们这样做,他们将拥有与付费应用收据绑定的 IAP。免费的 IAP 收据包含交易标识符;服务器可以使用交易ID来消除重复的购买。