120

How do I sign the .ipa file with a provisioning profile after I generate an IPA like the following with a different provision profile? I would like to sign the IPA with an ad-hoc provisioning profile for beta testing, and then re-sign the exact IPA with an app submission provisioning profile for the app store.

/usr/bin/xcrun -sdk iphoneos PackageApplication -v "${RELEASE_BUILDDIR}/${APPLICATION_NAME}.app" -o "${BUILD_HISTORY_DIR}/${APPLICATION_NAME}.ipa" --sign "${DEVELOPER_NAME}" --embed "${PROVISONING_PROFILE}"
Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Johnny
  • 1,483
  • 3
  • 13
  • 10

9 Answers9

217

It's really easy to do from the command line. I had a gist of a script for doing this. It has now been incorporated into the ipa_sign script in https://github.com/RichardBronosky/ota-tools which I use daily. If you have any questions about using these tools, don't hesitate to ask.

The heart of it is this:

CODESIGN_ALLOCATE=`xcrun --find codesign_allocate`; export CODESIGN_ALLOCATE
IPA="/path/to/file.ipa"
PROVISION="/path/to/file.mobileprovision"
CERTIFICATE="Name of certificate: To sign with" # must be in keychain
# unzip the ipa
unzip -q "$IPA"
# remove the signature
rm -rf Payload/*.app/_CodeSignature
# replace the provision
cp "$PROVISION" Payload/*.app/embedded.mobileprovision
# sign with the new certificate (--resource-rules has been deprecated OS X Yosemite (10.10), it can safely be removed)
/usr/bin/codesign -f -s "$CERTIFICATE" Payload/*.app
# zip it back up
zip -qr resigned.ipa Payload

Your new signed app is called resigned.ipa

Cameron Lowell Palmer
  • 21,528
  • 7
  • 125
  • 126
Bruno Bronosky
  • 66,273
  • 12
  • 162
  • 149
  • 35
    7 up votes and not a single question. I guess my bash is just that clear. – Bruno Bronosky Feb 05 '13 at 20:35
  • im getting an error message saying "security: unable to open "/var/folders/74/kpcwmb6j1pn92kr8mtvm2mwh0000gn/T/./resign.I9DrKi7B/Payload/AtlantaJournal.app/embedded.mobileprovision" for reading: No such file or directory". – Rahmathullah M Mar 14 '13 at 06:00
  • 3
    @RahmathullahMPulikkal I see I had errantly hardcoded a path in the gist. You really should be using https://github.com/RichardBronosky/ota-tools/blob/master/ipa_sign instead of the gist. It's the maintained code. – Bruno Bronosky Mar 29 '13 at 03:54
  • I got this error _security: unable to open "/tmp/resign.MyApp.WObe2/my.mobileprovision" for reading: No such file or directory_ easily fixed by moving the cp up in the code. Thank you! – Alberto M May 21 '13 at 13:25
  • @AlbertoM by moving what? I don't understand what it means. – iMx Sep 24 '13 at 15:18
  • @iMx, I just pushed an update that ought to fix this for you. – Bruno Bronosky Sep 24 '13 at 21:57
  • @RichardBronosky thanks, but I still get this error. But it works in terminal, if I enter the commands manually. – iMx Sep 25 '13 at 07:37
  • @iMx can you please send me a transcript of what does and doesn't work. Please include a `git log -1 | cat; git status` from within the ota-tools directory. – Bruno Bronosky Oct 26 '13 at 18:12
  • Thank you for commenting, @yeesterbunny. It encourages me to spend more time on stackoverflow... which is especially important when people choose not to accept the highest rated answers as "The correct answer." – Bruno Bronosky Feb 10 '14 at 03:07
  • after i run the script on the terminal, nothing happened, please advice – Mutawe Jun 09 '14 at 06:42
  • 5
    You may got an warning / error on --resource-rules parameters, which have been deprecated in OS X Yosemite (10.10), simply delete this parameter solve this issue. – ıɾuǝʞ Dec 17 '14 at 10:25
  • RichardBronosky many many thanks for this - spent hours trying different solutions before finding yours. Just to help future people - I needed the excellent pointer from @kenji which I almost didn't see as it was at the very end of the comments. I suggest adding this pointer into your answer or your script. – simmons Jan 07 '15 at 17:20
  • 4
    One little note: it looks like `CodeResources` is now located _inside_ of the `_CodeSignature` folder, so you just need to remove that folder. – dadude999 Jan 07 '15 at 22:20
  • @simmons comment added to the script – ıɾuǝʞ Jan 09 '15 at 15:06
  • After doing this, Application Loader still can't accept because the version is the same as the previous one – KarenAnne Feb 24 '16 at 07:05
  • 1
    @KarenAnne, changing the version number would be a different task than what was asked for by the OP. I would suggest looking for an answer to your task and asking a new question if you can't find it. – Bruno Bronosky Feb 24 '16 at 19:42
  • @BrunoBronosky I see. Because we cannot just re-submit new app to TestFlight by changing provisioning profile. It is not accepted by application if it has the same build and version number as the previous one. Thanks. – KarenAnne Feb 26 '16 at 02:31
  • @KarenAnne I think thin may be what you need. http://stackoverflow.com/questions/16975049/change-app-version-with-only-ipa-file-provided-no-xcode I haven't tried it yet but I'm going to work on it today. We can both report back and I'll add it to my answer if it works. Thanks for the idea. I'm always looking to improve my answers. – Bruno Bronosky Feb 26 '16 at 16:58
  • BTW, I was able to use the info in that answer to change the `CFBundleVersion` and `CFBundleShortVersionString` of an IPA for which I did NOT have the source code and submit it to TestFlight. My team was able to install and test the app. We shipped it to Apple and it is now in the store. I've modified ipa_sign to incorporate this feature and after more personal testing I'll release an update. – Bruno Bronosky Mar 22 '16 at 15:23
  • 1
    While this bash script works perfectly, if your app has entitlements it will not. You just need to add `security cms -D -i "$PROVISION" > provision.plist` `/usr/libexec/PlistBuddy -x -c 'Print :Entitlements' provision.plist > entitlements.plist` before copying the provisioning profile and then do `/usr/bin/codesign -f -s "$CERTIFICATE" --entitlements entitlements.plist Payload/*.app` instead of the current code signing. I only realised that the gist is the up to date version (handling entitlements) after reading the comments! – Rich Jun 07 '16 at 14:34
  • Hello, sorry I am totally new to bash and code signing :/ here is the error I get when executing the bash from a terminal window: Using temp dir: /tmp/resign. ... App has BundleDisplayName '...' and BundleShortVersionString '...' App has BundleIdentifier '...' and BundleVersion ... security: SecPolicySetValue: One or more parameters passed to a function were not valid. App has provision '...', which supports '...' security: unable to open "/tmp/resign..../....mobileprovision" for reading: No such file or directory ----> any thing I am doing wrong? – evilmandarine Jan 17 '17 at 17:33
  • 1
    `/usr/bin/codesign -f -s "$CERTIFICATE"` is not working anymore. It needs to be `/usr/bin/codesign --force -s "$CERTIFICATE" -v Payload/*.app` – Diana Farin May 10 '17 at 07:19
  • 2
    What worked for me today: Execute `security find-identity -v` to determine the ID of your signing identity. Invoke `/usr/bin/codesign --force -s YOUR_IDENTITY -v Payload/*.app` to actually sign the app. – Gene Aug 22 '17 at 15:27
  • You may need to add a step for extracting the current entitlements use it as part of codesign – MuthuKumar Haridoss Feb 11 '20 at 11:46
  • 1
    It's shows me unable to install the app after performing the steps. @BrunoBronosky any idea about this? – RushDroid Jul 20 '20 at 10:21
  • I'm facing the same issue as @RushDroid. Did you find any solution? – Sanket_B Oct 26 '20 at 13:03
  • zip -qr is what I was missing. I was using the compress option in Finder and was not working. – Satheesh Apr 12 '21 at 07:46
39

Check iResign for an easy tool on how to do this!

[edit] after some fudling around, I found a solution to keychain-aware resigning. You can check it out at https://gist.github.com/Weptun/5406993

CupawnTae
  • 14,192
  • 3
  • 29
  • 60
Blitz
  • 5,521
  • 3
  • 35
  • 53
16

Kind of old question, but with the latest XCode, codesign is easy:

$ codesign -s my_certificate example.ipa 

$ codesign -vv example.ipa
example.ipa: valid on disk
example.ipa: satisfies its Designated Requirement
BryanH
  • 5,826
  • 3
  • 34
  • 47
  • 2
    @Pavel This question was answered back when iOS 6.x was the latest version. Since then, we've had two major releases, which obviously changed many things. You might wish to limit your searches to answers that target current technology. – BryanH Jun 01 '15 at 16:16
  • 1
    It worked for me. you have to replace "my_certificate" with the name of the key in your key chain. – Franziskus Karsunke Oct 13 '15 at 13:58
  • 2
    `codesign` command is also used in @BrunoBronosky response. I'm not able to use it directly on "*.ipa" file, and the "-vv" options always returns `code object is not signed at all` on files that I know they are signed... – Mariano Paniga Dec 04 '15 at 10:28
16

The answers posted here all didn't quite work for me. They mainly skipped signing embedded frameworks (or including the entitlements).

Here's what's worked for me (it assumes that one ipa file exists is in the current directory):

PROVISION="/path/to/file.mobileprovision"
CERTIFICATE="Name of certificate: To sign with" # must be in the keychain

unzip -q *.ipa
rm -rf Payload/*.app/_CodeSignature/

# Replace embedded provisioning profile
cp "$PROVISION" Payload/*.app/embedded.mobileprovision

# Extract entitlements from app
codesign -d --entitlements :entitlements.plist Payload/*.app/

# Re-sign embedded frameworks
codesign -f -s "$CERTIFICATE" --entitlements entitlements.plist Payload/*.app/Frameworks/*

# Re-sign the app (with entitlements)
codesign -f -s "$CERTIFICATE" --entitlements entitlements.plist Payload/*.app/

zip -qr resigned.ipa Payload

# Cleanup
rm entitlements.plist
rm -r Payload/
simonseyer
  • 650
  • 1
  • 7
  • 14
  • 1
    Useful comment from the post above (Rich): https://stackoverflow.com/questions/5160863/how-to-re-sign-the-ipa-file#comment62841505_10905855 – Serzas Mar 19 '19 at 12:15
  • 1
    This is a great next step, but it is missing signing of extensions. I added one more line, before the app signing: codesign -f -s "$CERTIFICATE" --entitlements entitlements.plist Payload/*.app/Plugins/* – Pat Sep 01 '20 at 20:20
  • @Pat, what if appexes have different provisions? – Eugene Biryukov Oct 29 '21 at 12:00
  • I suppose you'd have to have a mapping or association of entitlements for each extension. Perhaps a folder that has the extension name and an entitlement for it, stored externally so you can do a for loop over the extensions and reference the appropriate entitlement by the extension name. – Pat Nov 05 '21 at 14:55
15

Fastlane's sigh provides a fairly robust solution for resigning IPAs.

From their README:

Resign

If you generated your ipa file but want to apply a different code signing onto the ipa file, you can use sigh resign:

fastlane sigh resign

sigh will find the ipa file and the provisioning profile for you if they are located in the current folder.

You can pass more information using the command line:

fastlane sigh resign ./path/app.ipa --signing_identity "iPhone Distribution: Felix Krause" -p "my.mobileprovision"

It will even handle provisioning profiles for nested applications (eg. if you have watchkit apps)

Community
  • 1
  • 1
mattliu
  • 823
  • 12
  • 28
8

I've updated Bryan's code for my Sierra iMac:

# this version was tested OK vith macOs Sierra 10.12.5 (16F73) on oct 0th, 2017
# original ipa file must be store in current working directory 

IPA="ipa-filename.ipa"
PROVISION="path-to.mobileprovision"
CERTIFICATE="hexadecimal-certificate-identifier" # must be in keychain
# identifier maybe retrieved by running: security find-identity -v -p codesigning

# unzip the ipa
unzip -q "$IPA"

# remove the signature
rm -rf Payload/*.app/_CodeSignature

# replace the provision
cp "$PROVISION" Payload/*.app/embedded.mobileprovision

# generate entitlements for current app
cd Payload/
codesign -d --entitlements - *.app > entitlements.plist
cd ..
mv Payload/entitlements.plist entitlements.plist

# sign with the new certificate and entitlements
/usr/bin/codesign -f -s "$CERTIFICATE" '--entitlements' 'entitlements.plist'  Payload/*.app

# zip it back up
zip -qr resigned.ipa Payload
Pierre Priot
  • 101
  • 1
  • 4
6
  1. Unzip the .ipa file by changing its extension with .zip
  2. Go to Payload. You will find .app file
  3. Right click the .app file and click Show package contents
  4. Delete the _CodeSigned folder
  5. Replace the embedded.mobileprovision file with the new provision profile
  6. Go to KeyChain Access and make sure the certificate associated with the provisional profile is present
  7. Execute the below mentioned command: /usr/bin/codesign -f -s "iPhone Distribution: Certificate Name" --resource-rules "Payload/Application.app/ResourceRules.plist" "Payload/Application.app"

  8. Now zip the Payload folder again and change the .zip extension with .ipa

Hope this helpful.

For reference follow below mentioned link: http://www.modelmetrics.com/tomgersic/codesign-re-signing-an-ipa-between-apple-accounts/

dsh
  • 12,037
  • 3
  • 33
  • 51
Dharmesh Siddhpura
  • 1,610
  • 12
  • 22
1

Try this app http://www.ketzler.de/2011/01/resign-an-iphone-app-insert-new-bundle-id-and-send-to-xcode-organizer-for-upload/

It supposed to help you resign the IPA file. I tried it myself but couldn't get pass an error with Entitlements.plist. Could just be a problem with my project. You should give it a try.

honcheng
  • 2,014
  • 13
  • 14
0

I have been using https://github.com/xndrs/XReSign and it is working really well.

Satheesh
  • 10,998
  • 6
  • 50
  • 93