重新签名IPA(iPhone)

154

我目前使用hudson构建所有应用程序,使用xcodebuild进行构建,然后使用xcrun进行构建,没有任何问题。

我收到了几个IPA文件,希望使用企业账户重新签名,而不是公司账户(用于App Store,或者有时是特定分发)。

我的问题是,当我尝试重新签名应用程序时,它无法安装在我的设备上(但它应该可以,因为这是一个企业版本)。错误消息显示在设备上(而不是在iTunes中),并且只告诉我它无法安装应用程序。没有更多信息。

我找到了一些资料,(http://www.ketzler.de/2011/01/resign-an-iphone-app-insert-new-bundle-id-and-send-to-xcode-organizer-for-upload/

而且这可能是可能的。我面临的问题是它似乎不能像我使用xcrun构建我的普通构建一样嵌入移动配置文件,是否可以使用codesign工具控制这个问题,或者是否可以使用xcrun重新签名?

使用我的重新签名脚本:

  • 解压app.ipa
  • appname=$(ls Payload)
  • xcrun -sdk iphoneos PackageApplication -s "$provisioning_profile" "$project_dir/Payload/$appname" -o "$project_dir/app-resigned.ipa" --sign "$provisioning_profile" --embed "$mobileprovision"

我查看了生成的ipa文件,它似乎非常类似于原始应用程序。这里真正需要更改的文件是什么?我最初认为_CodeSignature/CodeResources会更改,但内容看起来几乎完全相同。

非常感谢指针。

12个回答

223

终于搞定了!

使用cert1签名的IPA进行了测试,没有在配置文件中添加设备,可以提交到应用商店。为内部部署签署了一个企业帐户和移动配置文件,将移动配置文件嵌入到IPA中。

解决方法:

解压缩IPA文件

unzip Application.ipa

删除旧的CodeSignature

rm -r "Payload/Application.app/_CodeSignature" "Payload/Application.app/CodeResources" 2> /dev/null || true

替换嵌入的移动设备配置文件

cp "MyEnterprise.mobileprovision" "Payload/Application.app/embedded.mobileprovision"
重新签名。
/usr/bin/codesign -f -s "iPhone Distribution: Certificate Name" --resource-rules "Payload/Application.app/ResourceRules.plist" "Payload/Application.app"

重新打包

zip -qr "Application.resigned.ipa" Payload

编辑:已删除授权部分(请参见alleys的评论,谢谢)


6
导致我们问题的一件事是“权限文件”,如果有的话,必须与苹果提供的应用程序标识符相匹配。由于我们更改了包标识符,因此权限文件不匹配。应用程序可以运行,但钥匙串会在每次运行后清除。 - tjg184
5
根据http://oleb.net/blog/2011/06/code-signing-changes-in-xcode-4/的说法,应用程序ID已嵌入二进制文件中,因此只能使用相同的应用程序ID进行重新签名。我尝试使用不同的应用程序ID进行重新签名,但失败了。 - Michael Baltaks
8
您需要将之前的代码签名权限继承下来。顺便提一句,如果没有权限,推送通知将无法正常工作。解压后:/usr/bin/codesign -d --entitlements :entitlements.plist /Payload/appname.app 重新签名期间添加 --entitlements entitlements.plist - Peter
12
在Yosemite操作系统上,codesign签名失败--警告:--resource-rules在Mac OS X >= 10.10已被弃用!Payload/Aaa.app/ResourceRules.plist:无法读取资源。 - Jibeex
5
警告:--resource-rules 在 Mac OS X >= 10.10 已被弃用! Payload/Application.app/ResourceRules.plist:无法读取资源。出现此错误? - megha
显示剩余23条评论

66

这个问题的答案有点过时,而且缺少一些关键步骤,因此这是一个更新的指南,用于安装来自外部开发人员的应用程序。

----- 如何重新签名iOS应用程序 -----

假设你收到了来自另一个开发者的应用程序(例如MyApp.ipa),你想能够在你的设备上安装和运行它(例如使用ideviceinstaller)。

准备新的签名资产

第一步是获取包含您希望安装并运行在其中的所有设备的配置文件。确保配置文件包含您已经在您的钥匙串访问中安装的证书(例如iPhone开发人员:某人(XXXXXXXXXX))。下载配置文件(MyProfile.mobileprovision),以便您可以替换嵌入在应用程序中的配置文件。

接下来,我们将准备一个授权文件以包含在签名中。打开您的终端并运行以下命令。

$ security cms -D -i path/to/MyProfile.mobileprovision > provision.plist

这将创建一个描述您的 Provisioning Profile 的 xml 文件。接下来,我们想将授权转移到一个文件中。

$ /usr/libexec/PlistBuddy -x -c 'Print :Entitlements' provision.plist > entitlements.plist

替换配置文件并重新签名应用

如果你正在使用一个 .ipa 文件,首先需要解压该应用(如果你有一个 .app 文件,则可以跳过此步骤)。

$ unzip MyApp.ipa

现在您的工作目录中将会包含Payload/Payload/MyApp.app/。接下来,请删除旧的代码签名文件。

$ rm -rf Payload/MyApp.app/_CodeSignature

使用您自己的配置文件(即embedded.mobileprovision)替换现有的配置文件。

$ cp path/to/MyProfile.mobileprovision Payload/MyApp.app/embedded.mobileprovision

重要提示:您还必须重新签署应用程序中包含的所有框架。 它们位于 Payload/MyApp.app/Frameworks 中。如果应用程序使用 Swift 编写或包含任何其他框架,则必须重新签署这些框架,否则应用程序将安装但无法运行。

$ /usr/bin/codesign -f -s "iPhone Developer: Some Body (XXXXXXXXXX)" --entitlements entitlements.plist Payload/MyApp.app/Frameworks/*
现在使用您的预配文件中包含的证书和之前创建的entitlements.plist对应用程序进行签名。
$ /usr/bin/codesign -f -s "iPhone Developer: Some Body (XXXXXXXXXX)" --entitlements entitlements.plist Payload/MyApp.app

你现在可以重新压缩该应用程序。

$ zip -qr MyApp-resigned.ipa Payload

完成

现在您可以删除Payload目录,因为您已经拥有原始应用程序(MyApp.ipa)和重新签名版本(MyApp-resigned.ipa)。您现在可以在任何包含在您的预配文件中的设备上安装MyApp-resigned.ipa。


1
截至2017年3月9日,iOS 10.2和Xcode 8,这是我找到的唯一可行的解决方案。非常感谢! - allemattio
1
这个答案对我帮助很大!我忘记重新签署框架,导致应用在启动时崩溃。 - Rufus
我无法重新签署框架,因为在Payload/MyApp.app中没有Frameworks文件夹。有人能帮我解决这个问题吗?先谢谢了。 - i 4322946
1
如果您没有Frameworks文件夹,请忽略该步骤。顺便说一下,我刚刚使用grez提供的指令通过命令行重新签名了一个企业iOS应用,并成功部署了它。 - Jay
2
2023年有什么变化吗?我正在尝试完全相同的步骤,但安装后,iPhone显示“无法安装此应用程序,因为其完整性无法验证”。我做错了什么吗?@InnisBrendan,请提供任何意见。 - node_analyser
显示剩余5条评论

21

我认为最简单的方法是使用Fastlane:

sudo gem install fastlane -NV
hash -r # for bash
rehash # for zsh
fastlane sigh resign ./path/app.ipa --signing_identity "Apple Distribution: Company Name" -p "my.mobileprovision"

1
我尝试了许多方法,但都没成功。这个解决方案对我有用,谢谢。 - Omid Kia

12

我成功地按照此回答操作,但由于权限已更改,我只需删除倒数第二个语句中的--entitlements"Payload/Application.app/Entitlements.plist"部分,就可以完美地运行了。


我会赞同之前的评论。删除权限以使其与现代工具包兼容。 - Bruno Bronosky
2
没有权限文件,我的应用程序开始表现出奇怪的行为,并在日志中显示:SecItemCopyMatching: missing entitlement。我没有单独的Entitlements.plist文件,所以为了保留权限,我使用了@LordT的评论:首先创建一个权限文件:echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>/usr/bin/codesign -d --entitlements - temp/Payload/$APP_NAME | sed -E -e '1d'" > temp/newEntitlements,然后在签名时使用它:--entitlements temp/newEntitlements - Bulat

7

2020年,我使用了Fastlane进行操作 -

以下是我使用的命令

$ fastlane run resign ipa:"/Users/my_user/path/to/app.ipa" signing_identity:"iPhone Distribution: MY Company (XXXXXXXX)" provisioning_profile:"/Users/my_user/path/to/profile.mobileprovision" bundle_id:com.company.new.bundle.name

完整文档请见- https://docs.fastlane.tools/actions/resign/

6

使用Mac OS High Sierra和Xcode 10进行检查

您可以使用应用程序iResign来简单实现相同的操作。

请提供以下路径: 1).ipa文件 2)新的配置文件 3)授权文件(可选项,仅在有授权时添加) 4)Bundle id 5)发布证书

重新签名后,您可以看到输出的.ipa文件已保存

这是一个简单而强大的工具。


5

对我来说,这些辞职方法都不起作用,所以我必须想出其他办法。

在我的情况下,我有一个带有过期证书的IPA文件。我本可以重建应用程序,但因为我们想确保我们分发的是完全相同的版本(只是具有新证书),所以我们不想重新构建它。

与其他答案中提到的重新签名方法不同,我转向使用Xcode创建IPA文件的方法,该方法始于一个来自构建过程的.xcarchive文件。

  1. 我复制了现有的.xcarchive文件并开始替换其中的内容。(我忽略了.dSYM文件。)

  2. 我从旧的IPA文件中提取出旧的应用程序(通过解压缩;应用程序是Payload文件夹中唯一的内容)

  3. 我将此应用程序移动到新的.xcarchive文件中,在Products/Applications下替换原来的应用程序。

  4. 我编辑了Info.plist文件,编辑:

    • ApplicationProperties/ApplicationPath
    • ApplicationProperties/CFBundleIdentifier
    • ApplicationProperties/CFBundleShortVersionString
    • ApplicationProperties/CFBundleVersion
    • Name
  5. 我将.xcarchive文件移动到Xcode的归档文件夹中,通常是/Users/xxxx/Library/Developer/Xcode/Archives

  6. 在Xcode中,我打开了组织者窗口,选择了这个新的归档文件,并进行了常规(在本例中为企业级)导出。

结果得到了一个可行的,正常工作的IPA文件。


1
这是一个天才的解决方案,截至Xcode 9.2仍然有效。在我的情况下,我只是将旧的.app文件复制到现有的.xcarchive下。我没有更改Info.plist,因此应用程序版本保持为旧版本,但使用新的企业证书进行签名。 - dodgy_coder

1
使用Fastlane sigh的resign选项,您可以轻松地完成此操作。
sigh resign -p <path-to-profile-with-mobileprovision-ext> -i <code-sighning-identity-of-your-app>

你可以使用sigh下载配置文件,只需要在命令之前执行。

1

我尝试了所有的解决方案,最终使用以下命令成功创建重新签名的ipa文件

重新签名证书

  • *是ipa文件名和应用程序名称 $PROVISION是描述文件路径 $CERTIFICATE是钥匙串中证书的全名(双击证书可见的通用名称)
  1. 进入要创建新ipa的目录并安装证书和mobileprovision文件,在该目录下粘贴所有文件,包括ipa、证书和mobileprovision文件。

  2. 运行以下命令并将“mobile provision”替换为文件路径:security cms -D -i path/to/MyProfile.mobileprovision > provision.plist

  3. 运行以下命令:/usr/libexec/PlistBuddy -x -c 'Print :Entitlements' provision.plist > entitlements.plist

  4. 解压缩*.ipa文件:unzip -q *.ipa

  5. 删除Payload/*.app/_CodeSignature/目录:rm -rf Payload/*.app/_CodeSignature/

  6. 运行以下命令:/usr/libexec/PlistBuddy Payload/*.app/Info.plist(如果不需要更改bundle id,则可以忽略这3个步骤)

7.  Set :CFBundleIdentifier “com.mycompany.newbundleidentifier” (This should be new bundle ID)
8.  save
9.  quit
  1. 执行命令:cp $PROVISION Payload/*.app/embedded.mobileprovision

  2. 执行命令:codesign -d --entitlements :entitlements.plist Payload/*.app/ (如果应用程序无法运行,请忽略此命令,下次使用此命令)

  3. 执行命令:codesign -f -s "$CERTIFICATE" --entitlements entitlements.plist Payload/.app/Frameworks/

  4. 执行命令:codesign -f -s "$CERTIFICATE" --entitlements entitlements.plist Payload/*.app/

  5. 执行命令:zip -qr resigned.ipa Payload

https://dev59.com/7Gw05IYBdhLWcg3w_W1O#37172815 https://dev59.com/Am435IYBdhLWcg3w4UQc#50392448 https://coderwall.com/p/qwqpnw/resign-ipa-with-new-cfbundleidentifier-and-certificate


这个解决方案对我很有用。@InnisBrendan的回答也有效,但我们必须先签署框架,否则它将无法安装在设备上。 - Anjaneyulu Battula

0

如果您的APP是使用Flutter工具构建的,请检查所有pod扩展的codesign信息:

codesign -d --verbose=4 Runner.app/Frameworks/xxx.framework |& grep 'Authority='

结果应该是您团队的名称。

运行下面的 shell 脚本以 codesign 所有扩展:

IDENTITY=<prefix of Team ID number>
ENTITLEMENTS=<entitlements.plist>
find Payload/Runner.app -type d -name '*framework' | xargs -I '{}' codesign -s $IDENTITY -f --entitlements $ENTITLEMENTS {} 

最后别忘了对Runner.app本身进行codesign

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接