iOS-如何判斷安裝的APP被第三方企業(yè)證書(shū)重新簽名

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

具體方法如下:

1.用Charles抓了海馬助手的包,找到了下載ipa的鏈接,然后把對(duì)應(yīng)的ipa下載下來(lái)。

53DB0A6D-3E50-4332-8027-14F20AA3C0DD.png

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等。如下圖所示:

91618C5B-09A2-4C66-AF51-D4F7BF3A92BC.png

注意:此文件是二進(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ū)是不是你們自己的的啦。

D52EB29F-72AA-42AD-ABF3-6249B42C4026.png

只要我們讀取到里面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;
    
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容