您的位置:首页 > 移动开发

iOS APP反重签名技术详解

2015-01-04 00:55 435 查看
转载请注明出处,作者:秦伟

什么是签名?

简单的说,签名(signature)是苹果公司的一种安全机制,APP的签名有效才被iOS系统允许执行。

签名包含了开发者证书的信息等,如下图所示:



在Xcode中,找到 Build Settings -> Code Signing ,在此处设置签名。

什么是重签名?

重签名,就是在APP原来的基础上,用现有的签名替换原来的签名。

为什么要重签名?

1.在没有源代码的情况下,你已经对某个应用进行了资源修改(比如修改了启动图或图标等)。修改完成以后,如果想要让APP可以正常使用,该APP一定要重新签名然后压缩成IPA文件。

2.如果你想让你的APP不经过苹果审核,就可以私自发布到HTTPS服务器上,不越狱也能安装,且没有设备台数限制,那么你就要把个人开发者签名,替换成企业开发者In-House证书签名,之后OTA发布就行了。

3.一个开发者的应用,需要在另一个开发者帐号下发布到App Store。上传的ipa包,是重签名后的包。

4.过期或者失效签名的应用,正常使用需要重新签名。

如何重签名?

多数时候,当你有源代码,你想怎么设置签名就怎么设置,你可以把你的开发者证书换成别人的,或者把别人的开发者证书换成你自己的。

可是没有源码的情况下,你只有一个.app文件或者.ipa文件,这个时候,签名已经无法通过Xcode来修改了。你需要一个叫codesign的命令行工具来实现重签名。

codesign的语法就不介绍了,不在本文介绍范围内。

为什么要反重签名?

有没有想过,当你辛辛苦苦开发的APP,可能上架了App Store,也可能小范围内部传播,但你想过没有,别有用心之人可以想方设法篡改你的APP资源。

不要认为这没什么。往严重一点说吧,改改启动图、图标,算是轻的,如果连APP名也改了,把你的APP改头换面,再提交到AppStore,这就是盗版行为 !

如何实现反重签名?

原理:

1.每个签名都含有开发者证书的ID信息。

2.开发者证书的ID没有相同的。

首先,我们的开发者证书的ID字符串,在开发者证书导入钥匙串以后,可以在钥匙串中查到(10位大写字母加数字)。

Xcode工程里面,把这个字符串保存起来,宏定义一下。

APP启动时,检查APP的签名,读取开发者证书的ID字符串。

然后做对比,如果和预设的不一样,则视为签名被篡改了。

实现:

#import "AppDelegate.h"

// 证书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-identifier
NSString *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];

// 对比签名ID
if (![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


以上代码基本无需修改,仅需要在宏定义处,替换成你自己打包要用的开发者证书ID即可。

经过真机测试,重签名后,运行效果如下:






点击OK直接退出。

想要不带提示直接退出,请自行修改代码。

注意:模拟器上无效(因为模拟器上没有真机的环境,系统找不到描述文件,所以里面的代码不会执行)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  反重签名 ios ipa