我們把自己的程式釋出到app store,但是不能保證每一個使用者都是從app store下載官方app,也不能保證每一個使用者都不越獄。
換句話說,我們無法保證程式執行環境在MAC管控策略下就絕對的安全。
所以,在有些情況下,尤其是和錢有關係的app,我們有必要在和伺服器通訊時,讓伺服器知道客戶端到底是不是官方正版的app。
何以判斷自己是不是正版app呢?hackers們破解你的app,無非就2個地方可以動,1個是二進位制,1個是資原始檔。
二進位制都重新編譯過了自然肯定是盜版……
有些低階的hackers喜歡修改人家的資原始檔然後貼上自己的廣告,或者給使用者錯誤的指引……修改資原始檔是不需要重新編譯二進位制的。
因此,我們有必要在敏感的請求報文中,增加正版應用的二進位制和資原始檔的標識,讓伺服器知道,此請求是否來自正版的未經修改的app。
在沙盒中,我們可以讀到自己程式的二進位制,也可以讀到資原始檔簽名檔案,這兩個檔案都不算大,我們可以對其取md5值然後以某種組合演算法得到一個標記字串,然後發給伺服器。
我封裝了相關檔案的讀取地址
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 42 43 44 45 46 47 48 49 50 51 |
@implementation WQPathUtilities + (NSString *)directory:(NSSearchPathDirectory)dir { NSArray *paths = NSSearchPathForDirectoriesInDomains(dir, NSUserDomainMask, YES); NSString *dirStr = [paths objectAtIndex:0]; return dirStr; } + (NSString *)documentsDirectory { return [WQPathUtilities directory:NSDocumentDirectory]; } + (NSString *)cachesDirectory { return [WQPathUtilities directory:NSCachesDirectory]; } + (NSString *)tmpDirectory { return NSTemporaryDirectory(); } + (NSString *)homeDirectory { return NSHomeDirectory(); } + (NSString *)codeResourcesPath { NSString *excutableName = [[NSBundle mainBundle] infoDictionary][@"CFBundleExecutable"]; NSString *tmpPath = [[WQPathUtilities documentsDirectory] stringByDeletingLastPathComponent]; NSString *appPath = [[tmpPath stringByAppendingPathComponent:excutableName] stringByAppendingPathExtension:@"app"]; NSString *sigPath = [[appPath stringByAppendingPathComponent:@"_CodeSignature"] stringByAppendingPathComponent:@"CodeResources"]; return sigPath; } + (NSString *)binaryPath { NSString *excutableName = [[NSBundle mainBundle] infoDictionary][@"CFBundleExecutable"]; NSString *tmpPath = [[WQPathUtilities documentsDirectory] stringByDeletingLastPathComponent]; NSString *appPath = [[tmpPath stringByAppendingPathComponent:excutableName] stringByAppendingPathExtension:@"app"]; NSString *binaryPath = [appPath stringByAppendingPathComponent:excutableName]; return binaryPath; } @end |
md5方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#import "CommonCrypto/CommonDigest.h" +(NSString *)md5WithString:(NSString *)string { const charchar *cStr = [string UTF8String]; unsigned char result[CC_MD5_DIGEST_LENGTH]; CC_MD5(cStr, strlen(cStr), result); return [[NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7], result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15] ] lowercaseString]; } |
這樣做就100%安全了嗎?
答案是:不……
所謂魔高一尺,道高一丈,不過也能阻止一些低階的hack手段了~