iOS证书及ipa包重签名探究

By | 2015年4月12日

转载请注明出处:http://www.olinone.com/ 

        iOS证书学习推荐博客代码签名探析,本文重点在于介绍ios8.1.3系统ipa包重签名(如企业证书)无法安装的问题。苹果在iOS8.1.3系统以后加强了对ipa安装包签名的验证,主要区别在于ipa唯一标识在原有Bundle Identifier的基础上增加了证书ID,也就说安装包和手机上已安装APP的Bundle Identifier即使一致,如果两者签名的证书ID不相同,那么安装包也无法正常安装。证书ID是什么?

图中方框里字符串就是证书ID,升级后的ipa标识就是证书ID+BundleID,只有两者完全匹配,安装包才能覆盖安装,否则就会提示安装失败。解决办法就是卸载安装包,重新安装!

目前,重签名主要用于企业证书重签名个人证书发布的ipa包,包括各种助手及企业内测包的发布等。在重签名前,让我们先看看一个完整的ipa包有哪些与证书相关的东西!打开ipa包,会发现_CodeSignature和embedded.mobileprovision两个文件

  • _CodeSignature,ipa包签名文件
  • embedded.mobileprovision,证书配置文件

因此,替换上面两个文件就解决了ipa重签名的主要问题。此外,代码签名探析文中还提到entitlements.plist授权文件,重签名时也需要处理。按照下图内容创建plist文件,输入相关信息。

 

整个签名过程如下(文件路径自定义)

1、解压ipa安装包

2、替换证书配置文件(文件名必须为embedded,不得自定义)

3、重签名(certifierName为重签名证书文件名,可以加证书ID后缀)

4、打包

很多朋友在重签名时会忽略第二步或者没有指定entitlements.plist,都会造成ipa包安装失败。如果有其它关于签名的问题,可以在文章下面跟我留言!

喜欢请点赞->https://github.com/panghaijiao,谢谢你的来访!

 

9月22号更新,有朋友反馈9.0无法打开的问题,可以访问iOS9适配教程

6月22号更新,详情教程地址


 

12月21日,自从本文发布后,收到了很多朋友的反馈,感谢大家。很多朋友也提出了遇到的各种问题,再次需要补充两点

有些朋友希望修改bundle ID重签名,据有些朋友说是可以的,不过我目前还不知道怎么做,有知道的朋友可以告诉我,替各位谢谢了

其次,有些朋友希望修改ipa包里的素材,然后再签名,以我所知,这个貌似也行不通

 

154 thoughts on “iOS证书及ipa包重签名探究

  1. Pingback: WWDC 2015 将于 6 月 8 日在旧金山开幕 – iOS 移动开发周报 – 剑客|关注科技互联网

  2. Pingback: iOS移动开发周报-第43期 – 剑客|关注科技互联网

      1. 子非鱼

        输入codesign -f -s $certifierName –entitlements entitlements.plist的路径 提示cannot read entitlement data

        Reply
  3. Pingback: iOS移动开发周报-第43期

  4. Pingback: iOS移动开发周报-第43期 | 微时代

  5. 冷锋

    如果修改里面的图片资源,然后重新签名,能安装成功,但是闪退,如何解决

    Reply
      1. 冷锋

        您好,已经解决了,不知道什么原因,第二次重新打包就不闪退了,这边两台测试设备都是,第一次打包的一直闪退,重新打包后正常

        Reply
        1. ash

          你好,从App Store上下载的app,重签名后可以安装,但是打开闪退的问题,你解决了木有?我这边也是同样的问题。。

          Reply
        2. Eight

          您说的二次打包是怎样的、我也试图去修改资源后重签、但是装的途中日志显示增加了好多 ._*(*是修改后的资源文件名称) ,能安装\就是闪退~ 您说的二次打包是怎样的?

          Reply
        1. 匿名

          你好,我想替换ipad包中的一个plist文件,该怎么做呢??

          Reply
      2. 冷锋

        另外,像QQ这种,打包之后能成功安装,但打开就闪退,如何解决呢

        Reply
        1. 冷锋

          刚测试的,上架到AppStore的app在7.1.2iPad 7.1.2iPhone4 8.1.2iPhone6 8.13iPhone6P 均可安装,但打开闪退。。。。必须最开始就是用企业证书打包的ipa ,重新签名后才可用

          Reply
          1. 庞海礁 Post author

            appstore的ipa包是经过加密的,重签名应该是不行的!没有试过,不是很清楚,有时间可以研究下。不过只要不是appstore的包,即使是开发签名的包也是可以用企业证书重签名的!

  6. 不曾拥有

    有一个问题想请教一下
    博主上面说 app 签名 主要与这两个文件有关
    _CodeSignature,ipa包签名文件
    embedded.mobileprovision,证书配置文件

    我自己测试的时候 一直没有用 entitlements.plist 这个文件
    我首先把 app 包里面的 _CodeSignature 备份一下, 然后删除
    接着调用 codesign -f -s ‘xxxxxxx’ xxx.app 直接签名
    然后这时候得到的app 打包 安装失败
    将重签之后的app 中的_CodeSignature 取出 与原来的 用 文本文件进行对比 发现是一样啊 但是却无法安装

    如果用博主的方式 添加一个 entitlements.plist 就能成功安装

    Reply
    1. 庞海礁 Post author

      是的,在重签名时必须指定entitlement.plist文件,因为打包后的签名证书和打包之前的签名证书是不同,如果不指定新的entitlement,那么就会出现两者不同无法安装的问题!

      Reply
      1. 不曾拥有

        感谢博主解答
        刚才又去看了一下 xcodebuild 的log 发现 其也是调用了一个 entitlements 文件

        Reply
    2. 庞海礁 Post author

      CodeSignature文件在codesign时系统会为我们重新生成的,所以不需额外处理!

      Reply
      1. 不曾拥有

        是的 codesign 是会自动创建CodeSignature 文件
        我之前只是疑惑, 为什么原始app 能安装
        codesign -f -s ‘xxx’ 不加 entitlement.plist 签名之后的app 就不能安装
        于是 就把原始CodeSignature 与 签名之后的 CodeSignature 拿出来对比 发现是一样的

        Reply
  7. applled

    如果是企业证书,创建in house类型的pp文件的时候,现在貌似不能选择带通配符的app ID了。除了每个应用都建一个Explicit app ID,博主有没有其他方法呢?

    Reply
    1. 庞海礁 Post author

      现在苹果对证书签名管理比较严格,目前通配符好像是不行了,很遗憾,我也不知道如何解决通配符的问题!

      Reply
  8. victor3345

    在签名的时候遇到
    iPhone: ambiguous (matches “iPhone Developer:xxxxxxxx” adn “iPhone Distribution:xxxxxxxxxxxxxxxxx” in/Users/km-cn/Library/Keychains/login.keychain
    请问是原因,我查了下,没有重复的证书

    Reply
    1. 庞海礁 Post author

      按提示意思应该是你证书选错了吧?把开发的和发布的证书搞混了!

      Reply
      1. victor3345

        不像是你说的那样,我删一个报错的证书,就会报另一个错证书的错,最后只剩下我要签名的证书,就会报Distribution:: No such file or directory

        Reply
        1. 庞海礁 Post author

          重签名的时候需要用Distribution证书才能签名,你可以先在xcode中设置好发布证书,然后用Archive打包,如果打包成功表面证书是对的,在xcode中查看当前发布证书名,设置到脚本中就可以了

          Reply
  9. victor3345

    证书是正确的,用iResign这个工具也是直接报这个错

    Reply
  10. victor3345

    用iResign我弄好了,但是如果不修改identifiers 会报 Product identifiers don’t match,你知道需要改么

    Reply
    1. 庞海礁 Post author

      identifiers与证书必须一一对应,特别distribution证书,不然就会出现证书与identifiers不一致的问题

      Reply
  11. 匿名

    下了一个破解版本的微信,包中并没有entitlements.plist文件,倒是有xcent,然后改了相应的info文件中的bundleID,以及xcent文件中的application-identifiervalue字段为我证书的bundleID,签名之后总是提示安装失败,我是不是要自己copy一个entitlements.plist文件进来呢?

    Reply
    1. 庞海礁 Post author

      entitlements.plist文件是没有的,主要记录了安装包的基本信息,需要自己根据app的bundle ID以及其它信息填充修改的

      Reply
  12. 匿名

    非常感谢妹子的分享,我已经搞定了。只是里面还有一个小细节就是 Info.plist 重新设置一下Bundle identifier 等内容。

    Reply
    1. 庞海礁 Post author

      我晕,俺是真正的汉子,不是妹纸,谢谢!

      Reply
    2. 匿名

      你好 ,我遇到了同样地问题,请问需要怎么修改啊?

      Reply
    3. 李聪

      你好 我遇到了同样地问题,请问需要怎么修改啊?

      Reply
    1. 庞海礁 Post author

      是的,这块我还没有研究,不知兄台有相关资料推荐吗?或者有比较完整的解决方案吗?

      Reply
  13. 石大碗

    想请教下。我现已有的一个ipa(bundleID为 com.aa.bb)是用证书(ID:111)打包的版本,现在想用企业证书重签名。
    我的操作如下
    1、用企业证书添加一个ID为 com.aa.bb.enterprise的证书(ID:222),然后拿到授权文件 com.aa.bb.enterprise.mobileprovision
    2、构造 entitlements.plist,将其中的ID和包名全都改成222 和 com.aa.bb.enterprise
    3、然后删掉_CodeSignature,替换掉embedded.mobileprovision,再重新签名。
    最后一直是安装不了。请问错在哪了?

    Reply
    1. 庞海礁 Post author

      ipa有 watch或者其它扩展功能吗,把它们去掉,重签名目前只解决了安装包的签名问题,像watch其它没有重签名。安装的时候也可以查看手机日志,看看提示内容!

      Reply
      1. 石大碗

        并没有任何扩展功能,只是一个带百度地图的小软件。。
        另外,想请教下我的操作方法是否哪里有错??

        Reply
        1. 庞海礁 Post author

          企业证书是发布证书吗?还有安装出错日志提示啥?

          Reply
    2. 我也是遇到这样的问题,请问下 你解决了吗?有没被的解决方案

      Reply
      1. 我也是遇到这样的问题,请问下 你解决了吗?有没解决方案

        Reply
  14. Leezz

    请问博主,此方法可以让重签名的ipa与appstore的ipa覆盖安装吗?我现在能同时安装两个,无法做到覆盖安装。

    Reply
    1. 庞海礁 Post author

      文章里面已经说了,现在安装包需要验证证书ID+ipa bundleID,如果你重签名的是企业证书,肯定是无法和appstore的开发证书相兼容的,appstore可以覆盖企业版,但是企业版无法覆盖appstore的!

      Reply
  15. sam

    按照这个方法从appStore下载一个ipa,然后用企业证书重签名,安装闪退,有什么办法?

    Reply
    1. 庞海礁 Post author

      appstore的我没有试验过,不清楚,不过appstore的包一般是加密过的,应该不能重签名安装吧!

      Reply
      1. Ryze

        请问博主:
        我用企业证书打包并运行在多个设备的程序,证书在app developer被不小心删除了,现在的现象是,部分设备当天就不可用了,闪退。其余设备还正常可用。但是正常的设备也每天都不可用一些,原因是什么,博主能帮忙分析一下吗?非常着急,十分感谢。

        Reply
        1. 庞海礁 Post author

          设备里面的配置文件是有缓存的,系统在验证某个APP的配置文件时,会先验证ipa包里的配置文件,如果包里的配置文件与签名证书不匹配,会去手机的缓存中寻找匹配签名证书的匹配文件,如果都没有,该ipa包就无法安装或者运行不了。你可以在Xcode-Window-Devices-旋转自己设备右键-Show Provisioning Profiles里面查看所有缓存的配置文件,当然,为了验证当前签名的配置,可以把缓存里面的所有文件删除,重新打包安装就知道签名文件已经已过期或有效了。我猜测苹果设备自己会隔断时间同步签名证书是否过期,如果过期就无法运行ipa,出现崩溃的现象!对于过期的app,会在手机界面该icon名称右边标识一个红点,和刚更新app名称右边有个小点一样,只是颜色不同,希望对你有帮助!

          Reply
    2. 匿名

      App Store下载的ipa是经过加壳的, 如果想要二次签名 , 需要用脱壳工具破壳才行.

      Reply
  16. 吴欢

    请问博主,我7月31日重签名后的ipa安装成功。但是今天发现相同的ipa却安装失败。博主能帮忙分析一下是什么原因吗?十分感谢!

    Reply
    1. 庞海礁 Post author

      还是证书相互覆盖的问题,比如当前有两个3个安装包,一个个人开发证书签名包A,一个appstore上的包B,一个企业证书重签名的包C,个人开发证书A和appstoreB由于是同一签名,可以相互覆盖,企业重签名C与个人开发A签名不同无法相互覆盖,但是appstore由于由最高权限,可以覆盖企业重签名C,但是企业重签名无法覆盖appstore。所以你开始没装包,可以安装重签名的C,但是后来可能升级到appstore包B,然后就无法被企业重签名C覆盖的,但是你可以用个人证书签名A覆盖appstore,不知道你明白我意思没?要想一直安装覆盖企业包C,就无能被appstore的B覆盖,除了删除重装!企业C包只能自己覆盖自己!

      Reply
      1. 吴欢

        我发现一个奇怪的现象,当我Provisioning Profile选择Automatic的时候,打出的ipa包可以企业安装。但是当我Provisioning Profile选择企业发布证书的时候打出的包却安装失败(上周五安装成功,现在又不行了)。博主能帮忙分析一下原因么?十分感谢!
        我一般是这样试验的:先用企业发布证书打包,如果安装成功的话,就修改包里面的一个txt文件或者一张图片。一般修改之后是不能再安装了的。然后我再用企业发布证书重签名这个修改文件后的包,如果可以安装就说明重签名成功。我上周五整个流程都跑通了,可是今天再次测试的时候却都是安装失败,只有那个Provisioning Profile选择Automatic打的包可以成功安装。

        Reply
      2. 匿名

        多谢博主的耐心解答疑惑!我的问题已经解决了,原因是企业发布证书被撤销的缘故。

        Reply
      3. xz

        你好,我测试如下情况:企业AppA1.0 —重签名改bundle id — 企业AppB1.0 — 企业AppA1.1 覆盖安装,会出现两个App,不会覆盖安装,怎么解决啊?

        Reply
        1. 庞海礁 Post author

          修改bundle就相当于两个APP,系统区别APP就是通过bundle id区别的,所以想覆盖是不能修改bundle的

          Reply
  17. 刘凡

    你好,我用了您的方法。
    在修改了embedded.mobileprovision和相应的entitlements.plist文件之后。
    生成了一个企业版的ipa。
    该ipa在ios7上安装和**使用**没问题。
    可以再ios8上安装没问题。一打开就会闪退。
    请问这个是因为什么您知道吗?
    期待您的解答。

    Reply
    1. 庞海礁 Post author

      你这个说的太简单,app store上的包是无法重签名安装的

      Reply
      1. mxf

        结论:1.appStore上包是用企业证书签名后,在7.x上可以安装,但是无法启动,直接闪退。2.在8.x上无法安装。
        楼主,有办法可以用企业证书,重新签名已经发布到appStore上的ipa包吗?就能达到,各种助手达到的效果,就可以了。【就是公司开发一个app,可以通过企业级和appstore发布,app使用的微信、支付宝等都可以正常使用】?
        谢谢!

        Reply
  18. iGeek

    您好,请问有可以不改变bundleidentifier的重签名方法吗?
    类似某些苹果助手就是没有改变bundleidentifier实现了重签名,知道的话告知我一声…谢谢

    Reply
    1. 庞海礁 Post author

      文中介绍的重签名无需改变bundleidentifier

      Reply
      1. iGeek

        例如:我签名前的bundleidentifier为com.abc.mob……我用另外的bundleidentifier(如:com.def.uio)生成的证书进行重签名…..那么重签名后的bundleidentifier还会是com.abc.mob吗?

        Reply
          1. xiong

            用你给的方式重新签名安装一直失败,但是用 iReSign重签就可以,而iReSign 又做不到换账号重新签名bundle id不变,一直提示iresign product identifiers don’t match, 求解博主

          2. 庞海礁 Post author

            我这边目前测试是可以安装的,可以再仔细试试,有什么问题可以给我留言!

          3. xiong

            我找到重签一直安装失败的原因,我写的命令中包含有路径,生成的包也会包含。再请教楼主一个问题,企业版AppA bundle A,我重签名,entitlements.plist 中的bundle id 我填的是B
            重签名之后,覆盖安装报错 502: Upgrade’s application-identifier entitlement string (XXXX.com.shidou.wificlient.enterprise) does not match installed application’s application-identifier string (XXXX.com.shidou.client.enterprise.test); rejecting upgrade. 如果entitlements.plist的bundle id我填写的是A,覆盖安装报错Entitlements found that a