最近项目遇到IOS App被重签名二次打包的情况,于是研究一下App重签名方法和如何防护重签名。IOS签名校验是一个复杂的过程,但是任何系统都是有漏洞的。通过漏洞第三方可以定义App 重签名或者修改包里的资源文件甚至是代码逻辑。
重签名
1.重签名首先需要下载应用包(ipa)文件。
2.通过砸壳工具砸壳生成app文件,这里网上有很多教程。
3.通过第三方打包工具二次打包。如果没有苹果证书只有破解证书,那么二次打包的App只能在越狱设备上使用。如果想在未越狱的设备上运行,就需要一个苹果签发的证书。通配符的企业签名证书是最好的一种证书,它可以签任何Bundlid的App。
其他的二次签名方法没有研究过,但是要在未越狱设备上运行苹果签发的证书是必要。
防重签名
1.签名文件
研究了IOS 签名机制后发现签名证书文件是App里的embedded.mobileprovision 文件。
2.文件解析
二次签名后签名文件也会比替换成二次打包的证书签名文件。
找到签名文件后,我们就想办法如何保证签名文件一致。
- MD5校验
最简单的方法就是读取签名的MD5只,每次启动读取签名文件校验MD5值是否一致。多次编译签名文件不会改变,除非换证书。 这种方法过于简单除暴,不过有效。
这是我写的一个工具读取app包的签名值。
- 解析签名文件
上面那种方法过于简单粗暴,如果不想换签名文件都需要改校验值的话,我们可以换一种校验方法。Bundle ID 与Team ID校验。具体方法看下面代码:
NSMutableDictionary *outDic = [NSMutableDictionary dictionary];
NSString *strPath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];
NSData *fileData= [NSData dataWithContentsOfFile:strPath];
NSString *strHash =[pHash sha1String:fileData];
[outDic setValue:strHash forKey:@"HASH"];
NSString *rawDataString = [[NSString alloc] initWithData:fileData encoding:NSASCIIStringEncoding];
NSRange plistStartRange = [rawDataString rangeOfString:@"<plist"];
NSRange plistEndRange = [rawDataString rangeOfString:@"</plist>"];
if (plistStartRange.location != NSNotFound && plistEndRange.location != NSNotFound) {
NSString *tempPlistString = [rawDataString substringWithRange:NSMakeRange(plistStartRange.location, NSMaxRange(plistEndRange))];
NSData *tempPlistData = [tempPlistString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *plistDic = [NSPropertyListSerialization propertyListWithData:tempPlistData options:NSPropertyListImmutable format:nil error:nil];
NSArray *applicationIdentifierPrefix = [plistDic objectForKey:@"ApplicationIdentifierPrefix"];
NSDictionary *entitlementsDic = [plistDic objectForKey:@"Entitlements"];
NSString *mobileBundleID = [entitlementsDic objectForKey:@"application-identifier"];
NSString *tempMobilID = [applicationIdentifierPrefix firstObject];
[outDic setValue:tempMobilID forKey:@"Eid"];
[outDic setValue:mobileBundleID forKey:@"Bid"];
}
以上方法通过App store 的TestFlight测试和重签名检查。后续会上正式版本。如果上App store 发布后有其他问题会持续更新。