Apple은 모순 된 진술과 함께 영수증 유효성 확인에 관한 두 개의 문서를 제공합니다. "Verifying Store Receipts"에서인앱 구매 영수증 인증 모순
:
참고 : iOS의 경우 구입 영수증의 내용과 형식이 개인 및 변경 될 수 있습니다. 응용 프로그램에서 영수증 데이터를 직접 구문 분석하지 마십시오..
// Check the validity of the receipt. If it checks out then also ensure the transaction is something // we haven't seen before and then decode and save the purchaseInfo from the receipt for later receipt validation. - (BOOL)isTransactionAndItsReceiptValid:(SKPaymentTransaction *)transaction { if (!(transaction && transaction.transactionReceipt && [transaction.transactionReceipt length] > 0)) { // Transaction is not valid. return NO; } // Pull the purchase-info out of the transaction receipt, decode it, and save it for later so // it can be cross checked with the verifyReceipt. NSDictionary *receiptDict = [self dictionaryFromPlistData:transaction.transactionReceipt]; NSString *transactionPurchaseInfo = [receiptDict objectForKey:@"purchase-info"]; NSString *decodedPurchaseInfo = [self decodeBase64:transactionPurchaseInfo length:nil]; NSDictionary *purchaseInfoDict = [self dictionaryFromPlistData:[decodedPurchaseInfo dataUsingEncoding:NSUTF8StringEncoding]]; NSString *transactionId = [purchaseInfoDict objectForKey:@"transaction-id"]; NSString *purchaseDateString = [purchaseInfoDict objectForKey:@"purchase-date"]; NSString *signature = [receiptDict objectForKey:@"signature"]; // Convert the string into a date NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss z"]; NSDate *purchaseDate = [dateFormat dateFromString:[purchaseDateString stringByReplacingOccurrencesOfString:@"Etc/" withString:@""]]; if (![self isTransactionIdUnique:transactionId]) { // We've seen this transaction before. // Had [transactionsReceiptStorageDictionary objectForKey:transactionId] // Got purchaseInfoDict return NO; } // Check the authenticity of the receipt response/signature etc. BOOL result = checkReceiptSecurity(transactionPurchaseInfo, signature, (__bridge CFDateRef)(purchaseDate)); if (!result) { return NO; } // Ensure the transaction itself is legit if (![self doTransactionDetailsMatchPurchaseInfo:transaction withPurchaseInfo:purchaseInfoDict]) { return NO; } // Make a note of the fact that we've seen the transaction id already [self saveTransactionId:transactionId]; // Save the transaction receipt's purchaseInfo in the transactionsReceiptStorageDictionary. [transactionsReceiptStorageDictionary setObject:purchaseInfoDict forKey:transactionId]; return YES; }
내가 제대로 이해하고 "In-App Purchase Receipt Validation on iOS"샘플 코드 보안 취약점에 대한 "완화 전략"의 일환으로, 구입 영수증을 구문 분석하고 검증하는 제공 아직
, 영수증을 확인하면 Apple이 영수증 형식을 변경하기로 결정하면 내 앱이 작동을 멈출 수 있습니다.
영수증을 확인하지 않으면 Apple의 "완화 전략"을 따르지 않고 내 앱이 공격에 취약합니다.
저주받은 경우, 저주받은 경우 저주합니다. 내가 빠진 것이 있습니까?
감사합니다. 나는 그 질문을하기 전에 이미 그들에게 피드백을 보냈다. ;) 서버를 사용할 수없는 경우 iOS 5.1 이하 버전을 실행하는 장치에 대해서만 제공하는 코드를 실행하는 것이 가장 좋은 방법이라고 생각합니다. 그렇게하면 영수증을 변경하면 피해가 제한됩니다. – hpique
그래, 그건 기본적으로 내 대답이야. Apple은 이전에는 권장하지 않았던이 작업을 허용했으며, 서버가 없다면 할 수있는 유일한 방법입니다 (Apple이 이해할 수있는 것처럼 보입니다). 개발자는 아니지만 iOS 5.1.x 및 그 이하의 호환성을 저해하지 않는 것은 Apple에 달려 있습니다.그들이 어떻게 할 수 있을지 모르겠다. 어쩌면 iOS 5가 더 이상 쓸모없는 제품 일 때 영수증 형식을 바꿀 수도있다 ... – WDUK