最近接了个需求,需要判断手机上安装的包是从第三方越狱渠道下载的,也就是你的APP被第三方从App Store拔下来后重新用他们的企业证书进行签名,放到他们的越狱商城上供用户下载。这里不讨论具体怎么重新签名,讨论如何判断你的APP被重新签名了。
具体方法如下:
1.用Charles抓了海马助手的包,找到了下载ipa的链接,然后把对应的ipa下载下来。
2.ipa其实就是个压缩包,把文件的扩展名修改成.zip就可以解压缩了,解压缩完获取到对应的APP,右键显示包内容,找到这个XXX.mobileprovision文件,xxx.mobileprovision是ios开发中的设备描述文件,里面有证书信息、调试设备的UUID信息、bundle identifier等。如下图所示:
注意:此文件是二进制格式不能直接打开,那么如何查看其中信息呢,baidu有很多方法,我用的是下面这种:
使用mac自带security命令行
用mac自带的命令security,cd到mobileprovision所在的文件夹,执行
security cms -D -i XXX.mobileprovision
会得到下面的dict结构的详细信息:下面是海马给我的APP重新签名后的信息:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AppIDName</key>
<string>resong</string>
<key>ApplicationIdentifierPrefix</key>
<array>
<string>RZJM442J8M</string>
</array>
<key>CreationDate</key>
<date>2017-01-23T05:40:10Z</date>
<key>Platform</key>
<array>
<string>iOS</string>
</array>
<key>DeveloperCertificates</key>
<array>
<data>MIIFiDCCBHCgAwIBAgIIZYIIqChm21AwDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTcwMTIzMDUyNzQ3WhcNMjAwMTIzMDUyNzQ3WjCBiTEaMBgGCgmSJomT8ixkAQEMClJaSk00NDJKOE0xLjAsBgNVBAMMJWlQaG9uZSBEaXN0cmlidXRpb246IEJyIEhvbGRpbmdzLCBMbGMxEzARBgNVBAsMClJaSk00NDJKOE0xGTAXBgNVBAoMEEJyIEhvbGRpbmdzLCBMbGMxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArp8MZlVUwiqtvaWHtes22BCUDHM5MOciVG6CdkWyYQJVf9fVEN6xHDkHRLP8vpnD260dIBxPcQLHWmUClphy24EKZocPBwO2gpPXF2U4IPshYBHTAweUHuwE+bolzOqa9Gm9nnxdH/GDXiF9qNczcvqhVqDM9mTIdjA3RUd3AKOs4j2R2VfCHlCg0rifL7WJxWihbY+vuVA9Tosrp09K7LGLpC3M2z5a00bPX8OCmdrQhSIMIAoOlSuzR6W7RACOSGm/+BbwdbcnqfSyKsBwHIUadsTDJ/LX+8KBjmn77F3J587YlDAuzZeQHj6uS/uYnV60apS+2070birC43e8lQIDAQABo4IB4zCCAd8wPwYIKwYBBQUHAQEEMzAxMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5hcHBsZS5jb20vb2NzcDAyLXd3ZHIwMTAdBgNVHQ4EFgQUE1+f/fuSeNqlWKSpmPFjkFempl0wDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSIJxcJqbYYYIvs67r2R1nFUlSjtzCCAQ8GA1UdIASCAQYwggECMIH/BgkqhkiG92NkBQEwgfEwgcMGCCsGAQUFBwICMIG2DIGzUmVsaWFuY2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2NlcHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRpZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cuYXBwbGUuY29tL2FwcGxlY2EvMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAzATBgoqhkiG92NkBgEEAQH/BAIFADANBgkqhkiG9w0BAQUFAAOCAQEAQ7mnLeR5/NWNlofsFw0+2Tg8eTYNFE4E3sKaf2yq7v4GYSstgGwitTOszQ/rCFoqPyTQuz5m4SwdDaMNyVn48Fq/N6c6+rwxJg0fAcZP13T0Is9F1QuN1yBQ6NJRc6AeTcAy6BXty/nkXU2AbNuQGVk46Yg00zMpExev24qm8Dyb/9HsTmozTMS2MkjvLh2CqJLStaUOeDqpGIjuG0eBBf30GNKhf05FP0lPJ88IpJEVTlBGUMtiOjF/LurUUc66oCvV+wW0uwsGxbwTREFse+i+hl4vIRDqKH/v+7xkvoAz+L29VzOxTOTTNAorvCXdkkQ8fOH0TEQ3K7n/yfNoDQ==</data>
</array>
<key>Entitlements</key>
<dict>
<key>keychain-access-groups</key>
<array>
<string>RZJM442J8M.*</string>
</array>
<key>inter-app-audio</key>
<true/>
<key>get-task-allow</key>
<false/>
<key>application-identifier</key>
<string>RZJM442J8M.com.brhod.resong</string>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>RZJM442J8M.*</string>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>RZJM442J8M.*</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>RZJM442J8M</string>
<key>aps-environment</key>
<string>production</string>
<key>com.apple.developer.siri</key>
<true/>
</dict>
<key>ExpirationDate</key>
<date>2018-01-23T05:40:10Z</date>
<key>Name</key>
<string>resong_dis</string>
<key>ProvisionsAllDevices</key>
<true/>
<key>TeamIdentifier</key>
<array>
<string>RZJM442J8M</string>
</array>
<key>TeamName</key>
<string>Br Holdings, Llc</string>
<key>TimeToLive</key>
<integer>365</integer>
<key>UUID</key>
<string>82a5bed2-3b37-4f3d-807d-83e45fb05e21</string>
<key>Version</key>
<integer>1</integer>
</dict>
</plist>
里面有一个重要的key:application-identifier,这里就可以判断签名证书是不是你们自己的的啦。
只要我们读取到里面plist的部分,再把,application-identifier对应的value和自己APP本身的APPID作对比,就可以分辨出是否被第三方企业证书重新签名过了。
3.使用OC代码获取证书签名的代码:
+ (BOOL)isFromJailbrokenChannel
{
NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey];
if (![bundleId isEqualToString:@"your bundle id"]) {
return YES;
}
//取出embedded.mobileprovision这个描述文件的内容进行判断
NSString *mobileProvisionPath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];
NSData *rawData = [NSData dataWithContentsOfFile:mobileProvisionPath];
NSString *rawDataString = [[NSString alloc] initWithData:rawData 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 getArrayValueForKey:@"ApplicationIdentifierPrefix" defaultValue:nil];
NSDictionary *entitlementsDic = [plistDic getDictionaryValueForKey:@"Entitlements" defaultValue:nil];
NSString *mobileBundleID = [entitlementsDic getStringValueForKey:@"application-identifier" defaultValue:nil];
if (applicationIdentifierPrefix.count > 0 && mobileBundleID != nil) {
if (![mobileBundleID isEqualToString:[NSString stringWithFormat:@"%@.%@",[applicationIdentifierPrefix firstObject],@"your applicationId"]]) {
return YES;
}
}
}
return NO;
}