Skip to content

Instantly share code, notes, and snippets.

@iMaz1n
Forked from ryantan/resign-ipa.md
Created April 26, 2023 21:49
Show Gist options
  • Save iMaz1n/3d6a6d2801a3b05ed18a61ff072b68c8 to your computer and use it in GitHub Desktop.
Save iMaz1n/3d6a6d2801a3b05ed18a61ff072b68c8 to your computer and use it in GitHub Desktop.
How to resign an .ipa

How to Resign an iOS App

Let's say you receive an app (e.g. MyApp.ipa) from another developer, and you want to be able to install and run it on your devices (by using ideviceinstaller, for example).

Or your certificates and provision profiles have expired and you want to provide a new build to your clients without having to make a new build on the latest XCode or iOS SDK.

Prepare New Signing Assets

The first step is to attain a Provisioning Profile which includes all of the devices you wish to install and run on. Ensure that the profile contains a certificate that you have installed in your Keychain Access (e.g. iPhone Developer: Some Body (XXXXXXXXXX) ). Download the profile (MyProfile.mobileprovision) so you can replace the profile embedded in the app.

Choose how painful you want the process to be

Painless - use fastlane

Using Fastlane is much easier:

  1. Install fastlane if not already installed

  2. Create a txt file Fastfile in a fastlane directory, (e.g. nano ./fastlane/Fastfile).

  3. Adapt the below contents

lane :resignipa do
  resign(
    ipa: "path-to-your-ipa-file.ipa",
    signing_identity: "Apple Distribution: Your name (your ID)",
    provisioning_profile: "path-to-you-provision-file.mobileprovision",
  )
end

Note the paths should be relative to the directory containing the fastlane directory.

  1. Run fastlane resignipa in the directory containing the fastlane directory.

Your should see something like:

[โœ”] ๐Ÿš€ 
[12:04:21]: Get started using a Gemfile for fastlane https://docs.fastlane.tools/getting-started/ios/setup/#use-a-gemfile
[12:04:23]: Driving the lane 'resignipa' ๐Ÿš€
[12:04:23]: --------------------
[12:04:23]: --- Step: resign ---
[12:04:23]: --------------------

... a list of all frameworks it also signs

[12:04:25]: Successfully signed path-to-your-ipa-file.ipa!
[12:04:25]: Successfully re-signed .ipa ๐Ÿ”.

+------+--------+-------------+
|      fastlane summary       |
+------+--------+-------------+
| Step | Action | Time (in s) |
+------+--------+-------------+
| 1    | resign | 2           |
+------+--------+-------------+

[12:04:25]: fastlane.tools finished successfully ๐ŸŽ‰

You should be done!

Painful - manually

If you don't have access to fastlane, or interested to understand the internals, or just really like pain, read on:

Next, we are going to prepare an entitlements file to include in the signing. Open up your terminal and run the following.

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

This will create an xml file describing your Provisioning Profile. Next, we want to extract the entitlements into a file.

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

Replace The Provisioning Profile and Resign App

If you are working with a .ipa file, first, unzip the app (if you have a .app instead, you can skip this step).

$ unzip MyApp.ipa

Your working directory will now contain Payload/ and Payload/MyApp.app/. Next, remove the old code signature files.

$ rm -rf Payload/MyApp.app/_CodeSignature

Replace the existing provisioning profile (i.e. embedded.mobileprovision) with your own.

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

Now sign the app with the certificate included in your provisioning profile and the entitlements.plist that you created earlier.

$ /usr/bin/codesign -f -s "iPhone Developer: Some Body (XXXXXXXXXX)" --entitlements entitlements.plist Payload/MyApp.app

IMPORTANT: You must also resign all frameworks included in the app. You will find these in Payload/MyApp.app/Frameworks. If the app is written in Swift or if it includes any additional frameworks these must be resigned or the app will install but not run.

$ /usr/bin/codesign -f -s "iPhone Developer: Some Body (XXXXXXXXXX)" --entitlements entitlements.plist Payload/MyApp.app/Frameworks/*

You can now rezip the app.

$ zip -qr MyApp-resigned.ipa Payload

Done

You may now remove the Payload directory since you have your original app (MyApp.ipa) and your resigned version (MyApp-resigned.ipa). You can now install MyApp-resigned.ipa on any device included in your provisioning profile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment