iOS APP反重签名技术详解
轉(zhuǎn)載請(qǐng)注明出處,作者:秦偉
什么是簽名?
簡(jiǎn)單的說(shuō),簽名(signature)是蘋(píng)果公司的一種安全機(jī)制,APP的簽名有效才被iOS系統(tǒng)允許執(zhí)行。
簽名包含了開(kāi)發(fā)者證書(shū)的信息等,如下圖所示:
在Xcode中,找到?Build Settings -> Code Signing ,在此處設(shè)置簽名。
什么是重簽名?
重簽名,就是在APP原來(lái)的基礎(chǔ)上,用現(xiàn)有的簽名替換原來(lái)的簽名。
為什么要重簽名?
1.在沒(méi)有源代碼的情況下,你已經(jīng)對(duì)某個(gè)應(yīng)用進(jìn)行了資源修改(比如修改了啟動(dòng)圖或圖標(biāo)等)。修改完成以后,如果想要讓APP可以正常使用,該APP一定要重新簽名然后壓縮成IPA文件。
2.如果你想讓你的APP不經(jīng)過(guò)蘋(píng)果審核,就可以私自發(fā)布到HTTPS服務(wù)器上,不越獄也能安裝,且沒(méi)有設(shè)備臺(tái)數(shù)限制,那么你就要把個(gè)人開(kāi)發(fā)者簽名,替換成企業(yè)開(kāi)發(fā)者In-House證書(shū)簽名,之后OTA發(fā)布就行了。
3.一個(gè)開(kāi)發(fā)者的應(yīng)用,需要在另一個(gè)開(kāi)發(fā)者帳號(hào)下發(fā)布到App Store。上傳的ipa包,是重簽名后的包。
4.過(guò)期或者失效簽名的應(yīng)用,正常使用需要重新簽名。
如何重簽名?
多數(shù)時(shí)候,當(dāng)你有源代碼,你想怎么設(shè)置簽名就怎么設(shè)置,你可以把你的開(kāi)發(fā)者證書(shū)換成別人的,或者把別人的開(kāi)發(fā)者證書(shū)換成你自己的。
可是沒(méi)有源碼的情況下,你只有一個(gè).app文件或者.ipa文件,這個(gè)時(shí)候,簽名已經(jīng)無(wú)法通過(guò)Xcode來(lái)修改了。你需要一個(gè)叫codesign的命令行工具來(lái)實(shí)現(xiàn)重簽名。
codesign的語(yǔ)法就不介紹了,不在本文介紹范圍內(nèi)。
為什么要反重簽名?
有沒(méi)有想過(guò),當(dāng)你辛辛苦苦開(kāi)發(fā)的APP,可能上架了App Store,也可能小范圍內(nèi)部傳播,但你想過(guò)沒(méi)有,別有用心之人可以想方設(shè)法篡改你的APP資源。
不要認(rèn)為這沒(méi)什么。往嚴(yán)重一點(diǎn)說(shuō)吧,改改啟動(dòng)圖、圖標(biāo),算是輕的,如果連APP名也改了,把你的APP改頭換面,再提交到AppStore,這就是盜版行為 !
如何實(shí)現(xiàn)反重簽名?
原理:
1.每個(gè)簽名都含有開(kāi)發(fā)者證書(shū)的ID信息。
2.開(kāi)發(fā)者證書(shū)的ID沒(méi)有相同的。
首先,我們的開(kāi)發(fā)者證書(shū)的ID字符串,在開(kāi)發(fā)者證書(shū)導(dǎo)入鑰匙串以后,可以在鑰匙串中查到(10位大寫(xiě)字母加數(shù)字)。
Xcode工程里面,把這個(gè)字符串保存起來(lái),宏定義一下。
APP啟動(dòng)時(shí),檢查APP的簽名,讀取開(kāi)發(fā)者證書(shū)的ID字符串。
然后做對(duì)比,如果和預(yù)設(shè)的不一樣,則視為簽名被篡改了。
實(shí)現(xiàn):
#import "AppDelegate.h"// 證書(shū)ID #define kIdentifier @"55R3QD4LZ2"@interface AppDelegate ()@end@implementation AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {// 反重簽名[self checkCodesign];return YES; }- (void)checkCodesign {// 描述文件路徑NSString *embeddedPath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];if ([[NSFileManager defaultManager] fileExistsAtPath:embeddedPath]) {// 讀取application-identifierNSString *embeddedProvisioning = [NSString stringWithContentsOfFile:embeddedPath encoding:NSASCIIStringEncoding error:nil];NSArray *embeddedProvisioningLines = [embeddedProvisioning componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];for (int i = 0; i < [embeddedProvisioningLines count]; i++) {if ([[embeddedProvisioningLines objectAtIndex:i] rangeOfString:@"application-identifier"].location != NSNotFound) {NSInteger fromPosition = [[embeddedProvisioningLines objectAtIndex:i+1] rangeOfString:@"<string>"].location+8;NSInteger toPosition = [[embeddedProvisioningLines objectAtIndex:i+1] rangeOfString:@"</string>"].location;NSRange range;range.location = fromPosition;range.length = toPosition - fromPosition;NSString *fullIdentifier = [[embeddedProvisioningLines objectAtIndex:i+1] substringWithRange:range];// NSLog(@"%@", fullIdentifier);NSArray *identifierComponents = [fullIdentifier componentsSeparatedByString:@"."];NSString *appIdentifier = [identifierComponents firstObject];// 對(duì)比簽名IDif (![appIdentifier isEqual:kIdentifier]) {UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"codesign verification failed." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];[alert show];}break;}}}}#pragma mark - UIAlertViewDelegate- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {exit(0); }@end
以上代碼基本無(wú)需修改,僅需要在宏定義處,替換成你自己打包要用的開(kāi)發(fā)者證書(shū)ID即可。
經(jīng)過(guò)真機(jī)測(cè)試,重簽名后,運(yùn)行效果如下:
點(diǎn)擊OK直接退出。
想要不帶提示直接退出,請(qǐng)自行修改代碼。
注意:模擬器上無(wú)效(因?yàn)槟M器上沒(méi)有真機(jī)的環(huán)境,系統(tǒng)找不到描述文件,所以里面的代碼不會(huì)執(zhí)行)
總結(jié)
以上是生活随笔為你收集整理的iOS APP反重签名技术详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【科创人】慧安金科马宇翔:人生级决策总会
- 下一篇: 使用AutoFac组织多项目应用程序