【iOS-iap防禦】驗證用戶付費收據!拒絕iap Cracker!!讓iphone越獄用戶無從下手!!!

轉載自【黑米GameDev街區】 原文連接: http://www.himigame.com/iphone-cocos2d/673.htmlhtml

對於iOS的應用安全這塊主要有兩塊是咱們開發者能夠避免的,一個是存儲數據加密,這個在上一篇文章Himi介紹了base64加密算法;另一個就是付費產品防禦!那麼本篇Himi來分享如何防禦越獄用戶的iap Cracker!java

對於iap Cracker這個插件,Himi簡單介紹下!ios

iap Cracker能夠說是iOS越獄用戶的終極利器阿,當今app Store的全部內置收費的遊戲,基本使用此插件進行秒購買無壓力!(對於那些收費下載的遊戲,對於越獄用戶來講,安裝個XX助手<你懂得~>就能夠免費體驗app store的全部遊戲,無論你下載收費仍是內置收費!)算法

iap Cracker能繞過appstore的付費流程,其方式是當用戶點擊付費產品進行購買後,iap Cracker模擬返回一個購買成功的消息(無需聯網,說白了,連post 數據給App store都沒有!),而後咱們應用中收到這個「假的」交易成功的消息直接給用戶加錢,加裝備,加各類….json

OK,對於iap Cracker就再也不多介紹了,下面Himi來分享如何防禦iap Cracker吧;安全

對於越獄用戶使用付費破解插件進行付費這個問題,其實Apple並無無論,而是已經在文檔中清晰的說明,只是不少童鞋並無發現,以下截圖:app

apple提示開發者付費要進行驗證付費收據! 原文apple dev官方文檔鏈接:iphone

https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide…ide

  下面Himi就詳細講解如何在咱們付費流程中加入iap防禦,步驟以下:函數

1. 首先將 json類庫和NSData+Base64類導入你的項目中,下載:

  json_base.rar (105 字節, 14 次)

2. 而後將Himi封裝的以下函數拷貝到你付費代碼所在的類中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
.h中:  
-( BOOL )putStringToItunes:(NSData*)iapData;  
 
.m中:  
 
#import "NSData+Base64.h"  
#import "NSString+SBJSON.h"  
#import "JSON.h"  
 
-( BOOL )putStringToItunes:(NSData*)iapData{ //用戶購成功的transactionReceipt  
 
     NSString*encodingStr = [iapData base64EncodedString];  
 
     NSString *URL=@ "https://sandbox.itunes.apple.com/verifyReceipt" ;  
     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; // autorelease];  
     [request setURL:[NSURL URLWithString:URL]];  
     [request setHTTPMethod:@ "POST" ];  
     //設置contentType  
     [request addValue:@ "application/json" forHTTPHeaderField:@ "Content-Type" ];  
     //設置Content-Length  
     [request setValue:[NSString stringWithFormat:@ "%d" , [encodingStr length]] forHTTPHeaderField:@ "Content-Length" ];   
 
     NSDictionary* body = [NSDictionary dictionaryWithObjectsAndKeys:encodingStr, @ "receipt-data" , nil];  
     SBJsonWriter *writer = [SBJsonWriter new ];  
     [request setHTTPBody:[[writer stringWithObject:body] dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]];  
     NSHTTPURLResponse *urlResponse=nil;  
     NSError *errorr=nil;  
     NSData *receivedData = [NSURLConnection sendSynchronousRequest:request  
                                                  returningResponse:&urlResponse  
                                                              error:&errorr];  
 
     //解析  
     NSString *results=[[NSString alloc]initWithBytes:[receivedData bytes] length:[receivedData length] encoding:NSUTF8StringEncoding];  
     CCLOG(@ "-Himi-  %@" ,results);  
     NSDictionary*dic = [results JSONValue];  
     if ([[dic objectForKey:@ "status" ] intValue]==0){ //注意,status=@"0" 是驗證收據成功  
         return true ;  
     }  
     return false ;  
}  

接着說下此方法的使用,通常付費代碼中,童鞋們確定會有以下函數:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- ( void )paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions //交易結果  
{  
     for (SKPaymentTransaction *transaction in transactions)  
     {  
         switch (transaction.transactionState)  
         {  
             case SKPaymentTransactionStatePurchased: //交易完成  
                  if ([self putStringToItunes:transaction.transactionReceipt]){  
                      //這裏給用戶添加錢阿,裝備阿什麼的  
                  }  
                    break ;  
              ......代碼省略  
          }  
      }  
}  

上面這個函數當獲取交易成功的消息都會進入到SKPaymentTransactionStatePurchased這個case中(無論是iap cracker模擬的仍是appstore真的反饋的消息), 那麼咱們通常不作iap防禦狀況下,會直接在此case中給用戶添加金幣阿,什麼的! 可是如上所說由於iap cracker也會模擬返回交易成功的消息,也會進入到這個case中,所以咱們在此與appstore再次進行一次收據驗證!

另外說一點當交易完成時appstore傳回來的transaction(SKPaymentTransaction)類中的transactionReceipt屬性裏包含AppStore返回通過簽名的收據信息!OK,咱們要的就是這個收據並將此收據post給appstore 的server進行收據驗證,因此在SKPaymentTransactionStatePurchased這個交易成功的case中再調用Himi封裝的函數if([self putStringToItunes:transaction.transactionReceipt]){} 進行再次確認下購買是否付費流程正確!

那麼下面詳細說下Himi封裝的這個putStringToItunes函數:

此函數中,首先咱們將傳入的收據data類型變量進行base64轉換成string類型,而後將此收據以json的形式發送給appstore進行驗證!這裏注意!必定要以json形式發送,不然appstore server端不識別!

最後再次利用json對appstore server返回的字段(json數據)進行解析,咱們只須要解析出 status 這個key的value便可!

當appstore驗證收據正確時咱們解析出來的 status 這個key的value值爲0(零)!

下面是appstore返回json數據的兩種形式:

1. 收據無效的狀況:

1
{ "status" :21002, "exception" : "java.lang.NullPointerException" }  

2.收據正確的狀況,以下圖(點擊放大):


最後你們須要注意的一點是,Himi封裝的函數中post的地址這裏要記得發佈的時候修改!

      由於當你沙盒測試的時候地址是:https://sandbox.itunes.apple.com/verifyReceipt

      可是正式發佈後post的地址應該是:  https://buy.itunes.apple.com/verifyReceipt

千萬不要發佈應用的時候別忘記修改這裏!

OK,本篇就介紹到這裏,但願對尚未作iap防禦的童鞋有所幫助!

相關文章
相關標籤/搜索