iOS - 验证私有应用商店的企业配置文件

Posted

技术标签:

【中文标题】iOS - 验证私有应用商店的企业配置文件【英文标题】:iOS - Validate enterprise provisioning profiles for private appstore 【发布时间】:2015-11-12 23:53:53 【问题描述】:

作为我们移动设备管理功能的一部分,我们为客户提供私人应用商店。管理员可以将 ipa 文件上传到我们的服务器,我们将允许托管设备直接安装这些企业应用程序。

当管理员上传ipa时,我们想做一些验证,如果ipa不符合要求,立即拒绝。具体来说:

    如果ipa是由企业证书以外的证书(如appstore证书)签名的,我们要拒绝它; 如果 ipa 由已过期的证书签名,我们希望拒绝它; 如果 ipa 由已撤销的证书签名,我们希望拒绝它。

我有以下问题:

    对于要求 #1,我注意到企业版本在 ipa 中有一个文件 embedded.mobileprovision,但应用商店版本没有该文件。检查该文件是否存在就足以确定上传的 ipa 是否为企业 ipa,还是有更准确的方法来识别非企业 ipa? 对于要求 #2,embedded.mobileprovision 中似乎有一个字段 ExpirationDate,我可以检查它的值以确定到期日期吗? 据我所知,上面的#1 和#2 是可能的,但在用户实际尝试安装 ipa 之前,#3 将无法验证。即,当管理员上传 ipa 时,我无法捕捉到错误,但我会允许这样做,用户将收到无法安装应用程序的错误。

提前致谢。

【问题讨论】:

[[NSBundle mainBundle] pathForResource:@"embedded.mobileprovision" ofType:nil]***.com/questions/17584426/…。看到类似的问题。你可以得到一些想法 @aelam 感谢您的回复。如果我错了,请纠正我,看起来该线程是关于检查应用程序代码中的构建类型。在我的情况下,我们不拥有该应用程序(因此我们无权访问其源代码),管理员上传他们自己的应用程序 - 并且这些应用程序已签名,因此我们无法将代码注入他们的应用程序。我们手头的只是一个 ipa 文件,我想要一种直接从这个 ipa 获取信息的方法。 【参考方案1】:

下面的代码完成了所需的任务。

Boolean foundMobileProvision = false;
Pattern mobileProvisionPattern = Pattern.compile("embedded\\.mobileprovision$");

while ((entry = zipStream.getNextEntry()) != null) 
    Matcher mobileProvisionMatcher = mobileProvisionPattern.matcher(entryName);
    if (!entry.isDirectory()) 
        if (mobileProvisionMatcher.find()) 
            foundMobileProvision = true;
            CMSSignedDataParser parser = new CMSSignedDataParser(new BcDigestCalculatorProvider(), zipStream);
            InputStream plistContentStream = parser.getSignedContent().getContentStream();

            Map<String, Object> mobileProvisionAttributes = PlistParser.parsePlistToMap(plistContentStream);

            plistContentStream.close();

            validateEnterpriseProvision(mobileProvisionAttributes);
        
    

zipStream.close();
if (!foundMobileProvision) 
    throw new InvalidEnterpriseProvisionException("Uploaded app must have a valid enterprise provisioning profile");


private void validateEnterpriseProvision(Map<String, Object> mobileProvisionAttributes) 
    Boolean provisionAllDevices = (Boolean) mobileProvisionAttributes.get(ios_MOBILE_PROVISION_ALL_DEVICES);

    if (provisionAllDevices == null || !provisionAllDevices) 
        throw new InvalidEnterpriseProvisionException("Uploaded app must have a valid enterprise provisioning profile");
    

    Date expirationDate = (Date) mobileProvisionAttributes.get(IOS_MOBILE_PROVISION_EXPIRATION_DATE);
    if (new Date().after(expirationDate)) 
        throw new EnterpriseProvisionExpiredException("Profile expired");
    

【讨论】:

【参考方案2】:

您的 ipa 文件中有一个 embedded.mobileprovision。

    解压,里面有个Payload/appName.app/ 找出 embedded.mobileprovision

尝试查看 Embedded.mobileprovision

它是一个二进制plist(plist是一种有点特殊的xml格式,但仍然是xml)。我可以用 atom 和 vim 查看它。你会注意到有不可读的前缀和后缀,忽略它们。 进入中心部分。您可以看到许多节点,例如 TeamIdentifier、AppIDName、ProvisionedDevices。它有很多员工。

根据您的要求,我找到了一些您可能需要的代码 在https://github.com/0xc010d/mobileprovision-read/blob/master/main.m

它检查mobileprovision的一些关键节点。小于4?

if ([option isEqualToString:@"type"]) 
    if ([plist valueForKeyPath:@"ProvisionedDevices"])
        if ([[plist valueForKeyPath:@"Entitlements.get-task-allow"] boolValue]) 
            printf("debug\n");
        
        else 
            printf("ad-hoc\n");
        
    
    else if ([[plist valueForKeyPath:@"ProvisionsAllDevices"] boolValue]) 
            printf("enterprise\n");
    
    else 
            printf("appstore\n");
    

关于解析器

您可以编写一个命令行解析器工具,也可以在 Google 上搜索。 步骤不难

    修剪后缀和前缀 获取一些节点的值,如ProvisionedDevicesProvisionsAllDevices 如果ProvisionsAllDevicestrue。接受。

完成

【讨论】:

以上是关于iOS - 验证私有应用商店的企业配置文件的主要内容,如果未能解决你的问题,请参考以下文章

个人资料不是“iOS App Store”个人资料

IOS 配置文件应用商店不是 AdHoc

iOS 应用上传到应用商店无效的配置文件

上传到 iOS 应用商店时出现错误“您的二进制文件无效”

将 iOS 应用程序提交到商店,但无需访问开发者计划帐户,而是提供配置文件和分发证书

如何通过命令行将 iOS 应用上传到应用商店