How to re-sign the ipa file? - ios

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}"

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

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

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

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/

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)

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

Unzip the .ipa file by changing its extension with .zip
Go to Payload. You will find .app file
Right click the .app file and click Show package contents
Delete the _CodeSigned folder
Replace the embedded.mobileprovision file with the new provision profile
Go to KeyChain Access and make sure the certificate associated with the provisional profile is present
Execute the below mentioned command:
/usr/bin/codesign -f -s "iPhone Distribution: Certificate Name" --resource-rules "Payload/Application.app/ResourceRules.plist" "Payload/Application.app"
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/

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.

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

Related

Resigned ipa do not install on ios devices

My organization has developer account (not enterprise) and have added me as a "team member" to the organizations team account and shared the developer certificate and development provisioning profile(includes 1 device). Using those, I could develop an app, archive and created an IPA from XCode (selected method of distribution as "Development") and exported to a folder on disk. When exported I have the following files created on my disk
DistributionSummary.plist
ExportOptiona.plist
manifest.pList
Packaging.log
app.ipa
The admin of my organization wants to resign this ipa to distribute to app store and followed all the steps mentioned below, with distribution certificate and dist. provisioning profile (app store). The resigned ipa is then distributed(OTA) to users and it will not install on their phones.
I followed the below steps to re-sign our ipa
unzip the app
unzip -q *.ipa
Remove the old signature
rm -rf Payload/*.app/_CodeSignature/
Replace embedded provisioning profile
cp "XXXXXXXXXX_distribution.mobileprovision" Payload/*.app/embedded.mobileprovision
Extract entitlements from app
codesign -d --entitlements :entitlements.plist Payload/*.app/
Re-sign embedded frameworks
codesign -f -s "iPhone Distribution: Certificate Name. (ABC44343XZ)" --entitlements entitlements.plist Payload/.app/Frameworks/
Re-sign the app (with entitlements)
codesign -f -s "iPhone Distribution: Certificate Name. (ABC44343XZ)" --entitlements entitlements.plist Payload/*.app/
Zip re-signed app
zip -qr resigned.ipa Payload
Cleanup
rm entitlements.plist
rm -r Payload/
Can I re-sign an app from a developer to distribute to app store? Can somebody tell me where I am going wrong? Any help is greatly appreciated.
Note: I'm answering what you're saying in the comments
[Update] I received an email from apple with the following issue to be fixed "Invalid Swift Support - The SwiftSupport folder is missing. Rebuild your app using the current public (GM) version of Xcode and resubmit it." Can anyone help me here?
I can't do it directly on comments as I don't have enough reputation.
When you unzip the .ipa the first time, you should see at least four folders: one is the Payload (where you do all the signing operations, and changes regarding configuration), Symbols, BCSymbolMaps and a SwiftSupport folder. When you do the zip you have to add also the SwiftSupport folder to the .ipa:
zip -qr yourNewApp.ipa Payload/ SwiftSupport/
After doing this, you upload through Application Loader or you can validate your .ipa running this:
/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool -v -f yourNewApp.ipa -u yourItunesConnectUser#mail.com

Code resign using Ipa not failing with Installaation error-IOS

I am doing it through command line .The code is from third party developer.Previously it is working.Now it says Installation failed.
I use following code to resign
Unzip the .ipa file
unzip app.ipa
Delete the current code signature file
rm -rf Payload/MyApp.app/_CodeSignature/
Add in the new provisioning profile
cp ~/Downloads/AdHoc.mobileprovision Payload/MyApp.app/embedded.mobileprovision
resign the code
codesign -f -s "iPhone Distribution: Company Certificate" --resource-rules Payload/MyApp.app/ResourceRules.plist Payload/MyApp.app
rearchive the app into an .ipa file
zip -qr app-resigned.ipa Payload/
You also need to resign Framework, Dylibs, Appex,... files too.
But for best way to find problem of install, open XCode->Device and select your iphone to view log message when install failed.

Resigning an iOS app (.monotouch-32 symlink)

I'm attempting to resign an app with a new provisioning profile. My generic steps are:
unzip *.ipa
rm *.app/_CodeSignature
cp Payload/*.app/embedded.mobileprovision
codesign -f -s "Cert" --entitlements entitlements.plist Payload/*.app
zip -r Resigned.ipa Payload
When I verify the app with verbose output I receive the message
A sealed resource is missing or invalid
This is followed by a list of .dll files in the .monotouch-32 folder with a message such as:
"file modified: /foo/bar/Payload/foo.app/.monotouch-32/Xamarin.Forms.Core.dll".
When I inspect the listed dll's, they are all .symlink's to their .monotouch-64 counterpart. Any specific .monotouch-32 file is not listed as modified.
Any ideas how I can get around this issue?
It might not be your only issue but zip requires the use of -y for symlinks.
If that does not help then please edit your question to add the commands (and their outputs) used to sign and verify. You should also compare the .ipa (.zip) before and after.
Hi I was facing similar issue. For Xamarin related ipa's its always better o resign the Monotouch and .dll files separately.Please check below command for same
sudo codesign -f -s "iPhone Distribution: abcd" --entitlements
entitlements.plist Payload/myApp.app/.monotouch-32/*.dll
Same for Monotouch-64
sudo codesign -f -s "iPhone Distribution: abcd" --entitlements
entitlements.plist Payload/myApp.app/.monotouch-64/*.dll
By executing the above commands all the files inside the Payload file will get resigned properly

re-sign IPA files

We have IPA file which is developed by another developer with his certificates.
We are trying to re-sign the IPA which is built and distributed using another developer certificate. Please let me know if you have done this before or have any idea about this.
Tried some solutions mentioned in below links however we were able to generate IPA but can't install it in a device.
We are trying it in iOS 8. Mac 10.10.
Re-signing is a multi-step process which can produce errors at each step. So please have patience and try to understand each step by itself.
# Start with files:
# .ipa-file 'MyApp.ipa'
# New provisioning profile 'profile.mobileprovision'
# Unpack the .ipa-file
unzip MyApp.ipa
# Extract the old entitlements from the binary
codesign -d --entitlements :- Payload/MyApp.app > entitlements_old.plist
# Extract the new entitlements from the provisioning profile
security cms -D -i profile.mobileprovision > profile.plist
/usr/libexec/PlistBuddy -x -c 'Print :Entitlements' profile.plist > entitlements.plist
Now there is a manual step to edit the entitlements.plist so the application-identifier is correct. Refer to the entitlements_old.plist as a reference, but note that the team identifiers at the beginning of the value should be different.
# Then replace the embedded provisioning profile
cp profile.mobileprovision Payload/MyApp.app/embedded.mobileprovision
# Re-sign the binary and update entitlements
#
# Note: replace "Firstname Lastname (TEAMID123)"
# with your certificate name
#
codesign -f -s "Firstname Lastname (TEAMID123)" \
--entitlements entitlements.plist \
Payload/MyApp.app
# Create ipa
zip -r MyApp2.ipa Payload/
Sadly, the error messages when something is wrong do not give any special information about what exactly is wrong. But it may be:
Wrong signing identity used
Entitlements mismatch between the binary and the provisioning profile
Try this software. It was working fine for me for re-signing IPA with enterprise certificates.
https://github.com/maciekish/iReSign

How to resign an app with app store provisioning profile to add beta-reports-active key?

In order to distribute apps via Apple's new Test Flight service the beta-reports-active key needs to be present. Currently I'm using Apple's bot server to distribute to the old Test Flight system with and Ad Hoc distribution profile. Using a post build trigger I want to take the archive that is created and build an App Store Distribution ipa that I can upload to iTunes Connect. I've written a script that does this. I use the xcrun command to build:
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "${APP}" -o "${APP_STORE_IPA}" --sign "${SIGNING_IDENTITY}" --embed "${PROVISIONING_PROFILE}"
The SIGNING_IDENTITY and PROVISIONING_PROFILE are both app store distribution certificates/profiles. So the provisioning profile is getting embedded in the ipa and it contains the beta-reports-active flag. However, when I look at the ipa to verify its entitlements it is not present.
What am I doing wrong? All information I've seen on this has just suggested regenerating the provisioning profile. I've done this and know the key is present. It is not getting added to the entitlements. I have a widget that gets bundled in the ipa as well. I am not resigning that.
You could always try using the xcodebuild export command:
xcodebuild -exportArchive -archivePath '{APP}' -exportPath '{IPA}' \
-exportFormat 'ipa' -exportWithOriginalSigningIdentity
or if you want a different profile and identity:
xcodebuild -exportArchive -archivePath '{APP}' -exportPath '{IPA}' \
-exportFormat 'ipa' -exportWithOriginalSigningIdentity \
-exportProvisioningProfile {profilename} -exportSigningIdentity {identityname}
See man xcodebuild for more info.
Alright so I think I've finally got this figured out. It seems as though the Bot Server may have a few kinks that Apple needs to iron out. I noticed that the Distribution IPA that is generated by the Bot Server lacks any of the required entitlements of my Application. I did a little searching and found other people are having the same problem. Here's a question that explains the issue really well: IPA created via Xcode bot fails to run for APNS but runs if built manually via Xcode itself or built as an archive by Xcode
So with this in mind I created and added an entitlement file to my project with the minimum entitlements I needed. I also did the same for the widget that is in my project. Then during my post integration trigger I read both entitlement files and add the necessary entitlements to it.
# Copy the Entitlements file out of the payload so we can update it
APP_ENTITLEMENTS="/tmp/distributionEntitlements.plist"
rm -rf ${APP_ENTITLEMENTS}
codesign -d --entitlements :${APP_ENTITLEMENTS} "/tmp/Payload/MyAppName.app"
WIDGET_ENTITLEMENTS="/tmp/widgetDistributionEntitlements.plist"
rm -rf ${WIDGET_ENTITLEMENTS}
codesign -d --entitlements :${WIDGET_ENTITLEMENTS} "/tmp/Payload/MyAppName.app/Plugins/${WIDGET_NAME}"
# Copy over the latest build the bot just created
echo "Copying latest Archive to /tmp/...";
cp -Rp "${XCS_ARCHIVE}" "/tmp/"
APP="/tmp/Archive.xcarchive/Products/Applications/MyAppName.app"
echo "Updating entitlements file"
/usr/libexec/PlistBuddy -c "Add :beta-reports-active bool true" ${APP_ENTITLEMENTS}
/usr/libexec/PlistBuddy -c "Add :aps-environment string production" ${APP_ENTITLEMENTS}
cat ${APP_ENTITLEMENTS}
echo "Updating widget entitlements file"
/usr/libexec/PlistBuddy -c "Add :beta-reports-active bool true" ${WIDGET_ENTITLEMENTS}
cat ${WIDGET_ENTITLEMENTS}
Then of course you have to codesign these apps again:
echo "Codesign the widget"
cp "${WIDGET_PROVISIONING_PROFILE}" "${APP}/Plugins/${WIDGET_NAME}/embedded.mobileprovision"
codesign -fv -s "${FULL_SIGNING_IDENTITY}" "${APP}/Plugins/${WIDGET_NAME}" --entitlements "${WIDGET_ENTITLEMENTS}" --preserve-metadata=resource-rules,requirements
echo "Codesign the app"
codesign -fv -s "${FULL_SIGNING_IDENTITY}" "${APP}" --entitlements "${APP_ENTITLEMENTS}" --preserve-metadata=resource-rules,requirements
echo "Creating .ipa"
# Remove any whitespace
FILENAME=${XCS_BOT_NAME// /}
echo "Filename: ${FILENAME}"
APP_STORE_IPA="/tmp/${FILENAME}_AppStore_${VERSION_NUMBER}.ipa"
rm "${APP_STORE_IPA}"
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "${APP}" -o "${APP_STORE_IPA}" --sign "${SIGNING_IDENTITY}" --embed "${PROVISIONING_PROFILE}"
After all this, I can upload this IPA to Apple and distribute it using their new TestFlight beta distribution tool.
I use the following commands to resign an ipa which may work for you. The basic technique is to unzip the ipa, add in the desired mobile provisioning profile, resign the code with the desired certificate and then zip into the new ipa.
unzip -q "${IPAFILE}"
cp "${PROV_PROFILE}" Payload/*.app/embedded.mobileprovision
/usr/bin/codesign -f -s "${SIGN_CERT}" --keychain "${KEYCHAIN}" \
--entitlements Payload/*.app/$APP-Entitlements.plist \
--resource-rules Payload/*.app/ResourceRules.plist Payload/*.app
zip -qr "${NEW_IPAFILE}" Payload
You may be able to leave out the --keychain option if you're using the standard keychain. The name of your Entitlements.plist file may be different. SIGN_CERT is the text name of your certificate. e.g. "iPhone Distribution: Blah Blah"
Be sure that the Entitlements plist has the same TEAM ID as your signing cert and provisioning profile.
Xcode adds this beta entitlement to your entitlement list automatically. You just have to make a new revision, click on the Team account under the identity, reselect your account and the new profile will be remade by iTunes connect.
After that, upload your new binary.
Once it is uploaded you can assign beta testers to your app, selecting the pre-release version and adding the internal or external beta testers to the list.
I hope it helped.
A better way of doing this would be set the Release provisioning profile to the App store profile. Then you won't need to provide the --embed flag and the beta reports flag will be true.
Then if you also need a adhoc build you can provide the same xcrun command --embed with the adhoc provisioning profile.
ARCHIVE = "${ARCHIVE_FOLDER}/Products/Applications/${PRODUCT_NAME}.app"
#Adhoc
/usr/bin/xcrun -sdk iphoneos PackageApplication -v ARCHIVE -o IPA_DESTINATION --sign "SIGNING_IDENTITY" --embed PATH_TO_PROVISIONING_PROFILE
#App Store
/usr/bin/xcrun -sdk iphoneos PackageApplication -v ARCHIVE -o IPA_DESTINATION --sign "SIGNING_IDENTITY"

Resources