Как стать автором
Обновить

Как защитить in-App Purchase от ломалок

Время на прочтение2 мин
Количество просмотров7.6K
До недавнего времени inApp Purchase был достаточно надежным механизмом защиты от взлома приложений. Если разработчик хотел, чтобы его приложение не попадало в список ломаных — он просто выпускал его бесплатным с продажами внутри. Схема работала. Но после появления в Cydia 'iAP Cracker' — ситуация изменилась.
Под катом описан метод, как можно вполне легально обойти эти ломалки.

Я задумался о защите от взлома inApp Purchase после того, как увидел статистику моего приложения IQ pro. Оно построено на модели freemium. В своей статистике я видел огромное количество продаж — а в статистике от Apple цифры были совершенно другие (намного меньше). Тогда я не следил за тем, какие ломалки бывают. Но когда в отзывах люди начали писать, что «пользуйтесь 'iAP Cracker'» — все стало ясно.

Метод защиты описанный ниже использует механизм, который Apple рекомендует при продаже с последующей проверкой и загрузкой данных с вашего сервера. По сути, я перенес проверку тикета с удаленного сервера на само приложение.
В качестве библиотеки для inApp Purchase используется MKStoreKit.

Шаги:
1. В MKStoreManager.h — включаем #define SERVER_PRODUCT_MODEL 1
2. Оригинальный — (BOOL)verifyReceipt — заменяем на:

- (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. Добавить в проект библиотеку для работы с JSON (http://code.google.com/p/json-framework )
4. Все :-)

Что происходит:
После получения receipt — он отправляется еще раз на сервера Apple для проверки, а по ответу можно уже опредилить все, что надо.
P.S. Метод не претендует на звание «самого лучшего». Если у вас, коллеги есть замечания и еще идеи по этому поводу — пишите.
Теги:
Хабы:
+28
Комментарии30

Публикации

Изменить настройки темы

Истории

Работа

iOS разработчик
23 вакансии
Swift разработчик
32 вакансии

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн