二进制和资源文件自检
原文链接 https://gaoxiaosong.github.io/2014/08/31/binary-resource-file-md5.html
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
我们把自己的程序发布到App Store,但是不能保证每一个用户都是从App Store下载官方APP,也不能保证每一个用户都不越狱。
换句话说,我们无法保证程序运行环境在苹果管控策略下就绝对的安全。
所以,在有些情况下,尤其是和钱有关系的APP,我们有必要在和服务器通信时,让服务器知道客户端到底是不是官方正版的APP。
何以判断自己是不是正版APP呢?Hackers们破解你的app,无非就2个地方可以动,一个是二进制,一个是资源文件。
二进制都重新编译过了自然肯定是盗版……
有些低级的Hackers喜欢修改人家的资源文件然后贴上自己的广告,或者给用户错误的指引……修改资源文件是不需要重新编译二进制的。
因此,我们有必要在敏感的请求报文中,增加正版应用的二进制和资源文件的标识,让服务器知道,此请求是否来自正版的未经修改的APP。
在沙盒中,我们可以读到自己程序的二进制,也可以读到资源文件签名文件,这两个文件都不算大,我们可以对其取MD5值然后以某种组合算法得到一个标记字符串,然后发给服务器。
我封装了相关文件的读取地址:
@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%安全了吗?
答案是:不……
所谓魔高一尺,道高一丈,不过也能阻止一些低级的Hack手段了~