最近接了個(gè)需求,需要判斷手機(jī)上安裝的包是從第三方越獄渠道下載的,也就是你的APP被第三方從App Store拔下來(lái)后重新用他們的企業(yè)證書(shū)進(jìn)行簽名,放到他們的越獄商城上供用戶(hù)下載。這里不討論具體怎么重新簽名,討論如何判斷你的APP被重新簽名了。
具體方法如下:
1.用Charles抓了海馬助手的包,找到了下載ipa的鏈接,然后把對(duì)應(yīng)的ipa下載下來(lái)。

2.ipa其實(shí)就是個(gè)壓縮包,把文件的擴(kuò)展名修改成.zip就可以解壓縮了,解壓縮完獲取到對(duì)應(yīng)的APP,右鍵顯示包內(nèi)容,找到這個(gè)XXX.mobileprovision文件,xxx.mobileprovision是ios開(kāi)發(fā)中的設(shè)備描述文件,里面有證書(shū)信息、調(diào)試設(shè)備的UUID信息、bundle identifier等。如下圖所示:

注意:此文件是二進(jìn)制格式不能直接打開(kāi),那么如何查看其中信息呢,baidu有很多方法,我用的是下面這種:
使用mac自帶security命令行
用mac自帶的命令security,cd到mobileprovision所在的文件夾,執(zhí)行
security cms -D -i XXX.mobileprovision
會(huì)得到下面的dict結(jié)構(gòu)的詳細(xì)信息:下面是海馬給我的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>
里面有一個(gè)重要的key:application-identifier,這里就可以判斷簽名證書(shū)是不是你們自己的的啦。

只要我們讀取到里面plist的部分,再把,application-identifier對(duì)應(yīng)的value和自己APP本身的APPID作對(duì)比,就可以分辨出是否被第三方企業(yè)證書(shū)重新簽名過(guò)了。
3.使用OC代碼獲取證書(shū)簽名的代碼:
+ (BOOL)isFromJailbrokenChannel
{
NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey];
if (![bundleId isEqualToString:@"your bundle id"]) {
return YES;
}
//取出embedded.mobileprovision這個(gè)描述文件的內(nèi)容進(jìn)行判斷
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;
}