Back to Home

How to protect in-app purchase from crackers

in-app purchase · xcode · ios · anti-hacking

How to protect in-app purchase from crackers

    Until recently, inApp Purchase was a fairly reliable mechanism for protecting against hacking applications. If the developer wanted his application to not get into the list of broken lines - he just released it for free with sales inside. The circuit worked. But after the appearance in Cydia 'iAP Cracker' - the situation has changed.
    Under the cat, a method is described how to completely legally circumvent these crackers.

    I thought about inApp Purchase hacking protection after seeing the statistics of my IQ pro application. It is built on a freemium model. In my statistics, I saw a huge amount of sales - and in Apple's statistics, the numbers were completely different (much less). Then I did not follow what kind of breakers are. But when people began to write in reviews that “use 'iAP Cracker'” - everything became clear.

    The protection method described below uses the mechanism that Apple recommends when selling, followed by checking and downloading data from your server. In fact, I transferred the ticket check from the remote server to the application itself.
    MKStoreKit is used as a library for inApp Purchase.

    Steps:
    1. In MKStoreManager.h - turn on #define SERVER_PRODUCT_MODEL 1
    2. Original - (BOOL) verifyReceipt - replace it with:

    - (BOOL)verifyReceipt:(NSData*)receiptData {
      //NSString *urlsting = @"https://sandbox.itunes.apple.com/verifyReceipt";
        NSString *urlsting = @"https://buy.itunes.apple.com/verifyReceipt";
        NSURL *url = [NSURL URLWithString:urlsting];
        NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
        NSString *st =  [receiptData base64EncodingWithLineLength:[receiptData length]];
        NSString *json = [NSString stringWithFormat:@"{\"receipt-data\":\"%@\"}", st];
        [theRequest setHTTPBody:[json dataUsingEncoding:NSUTF8StringEncoding]];
    	[theRequest setHTTPMethod:@"POST"];		
    	[theRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];    
    	NSString *length = [NSString stringWithFormat:@"%d", [json length]];	
    	[theRequest setValue:length forHTTPHeaderField:@"Content-Length"];	
        NSHTTPURLResponse* urlResponse = nil;
    	NSError *error = [[NSError alloc] init];  
    	NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest
    												 returningResponse:&urlResponse 
    															 error:&error];  
    	NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
        NSDictionary *dic = [responseString JSONValue];
        NSInteger status = [[dic objectForKey:@"status"] intValue];
    	BOOL retVal = NO;
    	if (status == 0) {
            retVal = YES;
        }
        return retVal;
    }
    


    3. Add a library for working with JSON to the project (http://code.google.com/p/json-framework)
    4. Everything :-)

    What happens:
    After receiving the receipt, it is sent again to the Apple server for verification, and by the answer you can already determine everything that is needed.
    PS The method does not claim to be the "best." If you, colleagues have comments and more ideas about this - write.

    Read Next