我一直在努力验证我想在iOS6和iOS7上运行的应用中的应用内购买收据。到目前为止,我的计划是: (a)首先进行纯粹的设备上收据验证而不连接到Apple服务器(如these Apple docs和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而不是二进制。
回过头来看the Apple docs,我发现一个短语“在iOS中,如果appStoreReceiptURL方法不可用(在旧系统上),你可以回退到验证SKPaymentTransaction对象的transactionReceipt属性App Store。有关详细信息,请参阅“使用App Store验证收据。”
似乎我可能做出了不正确的假设。我一直认为iOS6和iOS7收据的格式相同,只是从不同的地方获得。
来自SKPaymentTransaction ASCII的transactionReceipt属性的收据和来自NSBundle二进制文件的appStoreReceiptURL方法的收据?
您真的可以使用iOS6中的transactionReceipt获得的收据进行纯粹的设备上收据验证吗?
思考? 克里斯。
我再次观看了WWDC 2013会议“使用收据来保护您的数字销售”,似乎显然iOS6收据格式与iOS7格式不同。我希望Apple能在某处提供iOS6和iOS7的收据格式之间的比较。我还没有访问运行iOS7的硬件,由于应用程序内购买无法在模拟器上运行,我还无法访问示例iOS7收据。 :(
答案 0 :(得分:0)
没有。您必须通过外部服务器验证应用内购买。如果不这样做,那么愚弄应用购买机制就相当简单。
答案 1 :(得分:0)
您当然可以使用Apple发布的VerificationController中的代码摘录对transaction.transactionReceipt进行设备上的收据验证。我修改了它并在开发人员论坛上发布了名为VerificationControllerPBKSimple的代码。收据由Apple签署,因此这个过程是相当安全的,除非有人在他们的设备上混淆了您编译的Objective-C代码 - 直到被弃用的transaction.transactionReceipt消失。
您还可以对iOS7收据(不是transaction.transactionReceipt)进行设备上收据验证,但这需要一些奇特的编码。