我一直在努力验证要在 iOS6 和 iOS7 上运行的应用程序的应用内购买收据。到目前为止,我的计划是:(a) 首先在不连接到 Apple 服务器的情况下进行纯粹的设备收据验证(就像这些 Apple 文档和 WWDC 2013 会议“使用收据保护您的数字销售”中给出的那样),然后(b)第二次在我的服务器上进行收据验证。这样做两次应该会有所帮助,并且在我的服务器关闭的情况下,也会使事情更加安全。
我终于从 App Store 收到了一个示例收据,并且在设备上收据验证方面遇到了问题。我正在 iOS6 系统(iPad)上进行测试,并使用来自 SKPaymentTransaction 的 transactionReceipt (不是来自 NSBundle 的 appStoreReceiptURL)获取收据。这是我的收据样本:
{
"signature" = "AkkgbJWkOGHyXoigel4s39Ut37kiYv+sXwhTa6+ic6LJPOq3DLV3B2zi9aebiezw6nvbJKyFrIYh1mqiKHDp/gJ5RFrslWDxk7ntiKIs1eJ3bpFgDC733Au9f1zUctvAiFwN+9L/FOGWugddwnHMhh9N8eSPoK+BoYUX8ObeCxc7AAADVzCCA1MwggI7oAMCAQICCGUUkU3ZWAS1MA0GCSqGSIb3DQEBBQUAMH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEzMDEGA1UEAwwqQXBwbGUgaVR1bmVzIFN0b3JlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA5MDYxNTIyMDU1NloXDTE0MDYxNDIyMDU1NlowZDEjMCEGA1UEAwwaUHVyY2hhc2VSZWNlaXB0Q2VydGlmaWNhdGUxGzAZBgNVBAsMEkFwcGxlIGlUdW5lcyBTdG9yZTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMrRjF2ct4IrSdiTChaI0g8pwv/cmHs8p/RwV/rt/91XKVhNl4XIBimKjQQNfgHsDs6yju++DrKJE7uKsphMddKYfFE5rGXsAdBEjBwRIxexTevx3HLEFGAt1moKx509dhxtiIdDgJv2YaVs49B0uJvNdy6SMqNNLHsDLzDS9oZHAgMBAAGjcjBwMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUNh3o4p2C0gEYtTJrDtdDC5FYQzowDgYDVR0PAQH/BAQDAgeAMB0GA1UdDgQWBBSpg4PyGUjFPhJXCBTMzaN+mV8k9TAQBgoqhkiG92NkBgUBBAIFADANBgkqhkiG9w0BAQUFAAOCAQEAEaSbPjtmN4C/IB3QEpK32RxacCDXdVXAeVReS5FaZxc+t88pQP93BiAxvdW/3eTSMGY5FbeAYL3etqP5gm8wrFojX0ikyVRStQ+/AQ0KEjtqB07kLs9QUe8czR8UGfdM1EumV/UgvDd4NwNYxLQMg4WTQfgkQQVy8GXZwVHgbE/UC6Y7053pGXBk51NPM3woxhd3gSRLvXj+loHsStcTEqe9pBDpmG5+sk4tw+GK3GMeEN5/+e1QT9np/Kl1nj+aBw7C0xsy0bFnaAd1cSS6xdory/CUvM6gtKsmnOOdqTesbp0bs8sn6Wqs0C9dgcxRHuOMZ2tm8npLUm7argOSzQ==";
"purchase-info" = "ewoJIm9yaWdpbmFsLXB1cmNoYXNlLWRhdGUtcHN0IiA9ICIyMDEzLTEwLTE4IDE2OjQ3OjM4IEFtZXJpY2EvTG9zX0FuZ2VsZXMiOwoJInVuaXF1ZS1pZGVudGlmaWVyIiA9ICI5OTQ2ZTk0M2E4YTI3YzhlM2U0YzY4YmM1N2I5YWQ2MmUwOTFjNmUxIjsKCSJvcmlnaW5hbC10cmFuc2FjdGlvbi1pZCIgPSAiMTAwMDAwMDA5MDYwNjMzOSI7CgkiYnZycyIgPSAiMS4wIjsKCSJ0cmFuc2FjdGlvbi1pZCIgPSAiMTAwMDAwMDA5MDYwNjMzOSI7CgkicXVhbnRpdHkiID0gIjEiOwoJIm9yaWdpbmFsLXB1cmNoYXNlLWRhdGUtbXMiID0gIjEzODIxNDAwNTg3NjYiOwoJInVuaXF1ZS12ZW5kb3ItaWRlbnRpZmllciIgPSAiODBERjQ0RUItNkQ1OS00QTBBLUEwNkEtQzg2RjM0QTcwQ0ZDIjsKCSJwcm9kdWN0LWlkIiA9ICJiaXouU3Bhc3RpY011ZmZpbi5QZXR1bmlhLkFkUmVtb3ZhbFllYXJseSI7CgkiaXRlbS1pZCIgPSAiNzI3MTg5MzU4IjsKCSJiaWQiID0gImJpei5TcGFzdGljTXVmZmluLlBldHVuaWEiOwoJInB1cmNoYXNlLWRhdGUtbXMiID0gIjEzODIxNDAwNTg3NjYiOwoJInB1cmNoYXNlLWRhdGUiID0gIjIwMTMtMTAtMTggMjM6NDc6MzggRXRjL0dNVCI7CgkicHVyY2hhc2UtZGF0ZS1wc3QiID0gIjIwMTMtMTAtMTggMTY6NDc6MzggQW1lcmljYS9Mb3NfQW5nZWxlcyI7Cgkib3JpZ2luYWwtcHVyY2hhc2UtZGF0ZSIgPSAiMjAxMy0xMC0xOCAyMzo0NzozOCBFdGMvR01UIjsKfQ==";
"environment" = "Sandbox";
"pod" = "100";
"signing-status" = "0";
}
在我的设备收据验证中,我在转换为 PKCS #7 表示的步骤中失败了:
// Without (void *) coercion, we get a warning, but we're only reading from this buffer in BIO_new_mem_buf
b_receipt = BIO_new_mem_buf((void *) [self.receipt bytes], [self.receipt length]);
if (! b_receipt) {
endWithMessage(@"Failed on BIO_new_mem_buf: receipt"); return(ReceiptInvalid);
}
// Convert receipt data to PKCS #7 Representation
p7 = d2i_PKCS7_bio(b_receipt, NULL);
if (! p7) {
endWithMessage(@"Failed on d2i_PKCS7_bio"); return(ReceiptInvalid);
}
到目前为止,我对收据是 ASCII 而不是二进制的事实感到震惊。
在返回查看Apple 文档时,我发现一个短语“在 iOS 中,如果 appStoreReceiptURL 方法不可用(在旧系统上),您可以回退到使用 App Store 验证 SKPaymentTransaction 对象的 transactionReceipt 属性。对于详细信息,请参阅“使用 App Store 验证收据”。
看来我可能做了不正确的假设。我一直假设 iOS6 和 iOS7 的收据格式相同,只是从不同的地方获得的。
来自 SKPaymentTransaction ASCII 的 transactionReceipt 属性的收据和来自 NSBundle 二进制的 appStoreReceiptURL 方法的收据?
你真的可以在 iOS6 中使用通过 transactionReceipt 获得的收据进行纯粹的设备上收据验证吗?
想法?克里斯。
编辑
我再次观看了 WWDC 2013 “Using Receipts to Protect Your Digital Sales” 会议,显然 iOS6 收据格式与 iOS7 格式不同。我希望 Apple 能在某个地方提供 iOS6 和 iOS7 的收据格式之间的比较。不过,我还没有访问运行 iOS7 的硬件,并且由于应用内购买在模拟器上不起作用,我还没有访问示例 iOS7 收据。:(。