我們把自己的程序發(fā)布到 app store漏益,但是不能保證每一個(gè)用戶都是從 app store 下載官方 app楞捂,也不能保證每一個(gè)用戶都不越獄襟交。 換句話說(shuō),我們無(wú)法保證程序運(yùn)行環(huán)境在 MAC 管控策略下就絕對(duì)的安全鞋屈。 所以范咨,在有些情況下,尤其是和錢有關(guān)系的 app 厂庇,我們有必要在和服務(wù)器通信時(shí)渠啊,讓服務(wù)器知道客戶端到底是不是官方正版的 app 。
何以判斷自己是不是正版 app 呢权旷? hackers 們破解你的 app 替蛉,無(wú)非就 2 個(gè)地方可以動(dòng),1 個(gè)是二進(jìn)制拄氯,1 個(gè)是資源文件躲查。
二進(jìn)制都重新編譯過(guò)了自然肯定是盜版……
有些低級(jí)的 hackers 喜歡修改人家的資源文件然后貼上自己的廣告,或者給用戶錯(cuò)誤的指引……修改資源文件是不需要重新編譯二進(jìn)制的译柏。
因此镣煮,我們有必要在敏感的請(qǐng)求報(bào)文中,增加正版應(yīng)用的二進(jìn)制和資源文件的標(biāo)識(shí)鄙麦,讓服務(wù)器知道典唇,此請(qǐng)求是否來(lái)自正版的未經(jīng)修改的 app 。 在沙盒中胯府,我們可以讀到自己程序的二進(jìn)制介衔,也可以讀到資源文件簽名文件,這兩個(gè)文件都不算大骂因,我們可以對(duì)其取 md5 值然后以某種組合算法得到一個(gè)標(biāo)記字符串炎咖,然后發(fā)給服務(wù)器。
我封裝了相關(guān)文件的讀取地址
@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方法:
#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% 安全了嗎侣签?
答案是:不……
所謂魔高一尺塘装,道高一丈,不過(guò)也能阻止一些低級(jí)的 hack 手段了~