Posts

Post not yet marked as solved
3 Replies
1.1k Views
Facts:It's about checking in-app purchases. A sh1-hash and a receipt are transmitted to a server. This now checks via buy.itunes.apple.com/verifyReceipt the correctness of InApp purchases. If InApp purchases have not yet been activated on the device, then the device should now be informed. To prevent fraud, we used a sh1-hash.The hash is composed according to the following scheme:$s = ""; $arrID = array(); foreach ($return["value"]["inapp"] as $key => $row) { $arrID[$key] = $row['id']; } array_multisort($arrID, SORT_ASC, $return["value"]["inapp"]); // Sorting "id" ASC for($i = 0, $length = count($return["value"]["inapp"]); $i < $length; $i++) { $dic = $return["value"]["inapp"][$i]; if(array_key_exists('id', $dic)) $s .= "id" . ((int)$dic["id"]); if(array_key_exists('purchase_date_ms', $dic)) $s .= "purchase_date_ms" . ((int)$dic["purchase_date_ms"]); } $return["hash"] = sha1($hash . sha1($s));Where $hash is the hash value, which was transmitted to the server.On the server, the JSON is sent with the command:echo json_encode($return); exit();On the server header is:header('Content-Type: application/json; charset=utf-8'); header('Expires: Sun, 01 Jan 2014 00:00:00 GMT'); header('Cache-Control: no-store, no-cache, must-revalidate'); header('Cache-Control: post-check=0, pre-check=0', FALSE); header('Pragma: no-cache');In iOS, the communication is set up as follows:AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager]; [sessionManager setSecurityPolicy:policy]; [[sessionManager requestSerializer] setTimeoutInterval:10]; [[sessionManager requestSerializer] setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; [sessionManager POST:@"https://..." parameters:@{@"hash": [[CocoaSecurity sha1:deviceID] hexLower], @"isTest": @(isBetaVersion), @"receipt": sReceipt, @"identifier": deviceID, @"inApp": arrInAppItems } progress:^(NSProgress *uploadProgress){} success:^(NSURLSessionTask *task, id responseObject) { NSDictionary *response = (NSDictionary *)responseObject; if (response[@"hash"]) { NSMutableArray *arr = [response[@"value"][@"inapp"] mutableCopy]; [arr sortUsingDescriptors:[NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:@"id" ascending:YES], nil]]; NSMutableString *sHash = [@"" mutableCopy]; for (NSDictionary *d in arr) { if (d[@"id"]) [sHash appendFormat:@"id%ld", [d[@"id"] integerValue]]; if (d[@"purchase_date_ms"]) [sHash appendFormat:@"purchase_date_ms%ld", [d[@"purchase_date_ms"] integerValue]]; } NSString *hash = [[CocoaSecurity sha1:([[[CocoaSecurity sha1:deviceID] hexLower] stringByAppendingString:[[CocoaSecurity sha1:sHash] hexLower]])] hexLower]; } }];Problem:I found that the HASH on the device is not put together exactly like on the server.My first suspicion was that it has to do with the writing direction on some devices. However, this does not affect the result. Why is it? It concerns only very few devices.
Posted Last updated
.