If you’re an iOS developer, most likely you’ve had to deal with code signing. And if you’re a junior iOS developer, you might’ve felt a bit overwhelmed by everything going on in the “Certificates, Identifiers & Profiles” section of the developer portal.
The goal of this article is to help junior iOS developers understand code signing on a higher level. This will not be a step-by-step tutorial on how to code sign your app. Ideally, after reading this article, you will be able to code sign your app without following any tutorials.
I don’t plan to go into lower level details, but we will talk a bit about asymmetric cryptography.
The minimum you need to know is that asymmetric cryptography uses a public key and a private key. The users have to keep their private key for themselves, but they can share the public key. And using those public and private keys, a user can prove that he is indeed himself.
A good high-level explanation of asymmetric cryptography can be found here. If you want to know implementation details or the math behind this, you can find them online.
The App ID is the unique identifier of your app. It consists of a team id, generated by Apple (you don’t have any control over it) and your app’s bundle id (
com.youcompany.yourapp, for example).
There can also be wildcard App IDs:
com.yourcompany.*. Those will match on multiple bundle ids.
Generally, you will have an explicit App ID, not a wildcard one.
You have probably already noticed that in order to create a certificate in Apple’s developer portal, you need to upload a Certificate Signing Request. You can generate this CSR from the Keychain, and this CSR contains a private key.
Then on the developer portal, you can create a certificate using this CSR.
There can be multiple types of certificates. The most common are:
- Development (iOS App Development) - You need those to run your app on a device from Xcode.
- Distribution (App Store and Ad Hoc) - You need those to be able to distribute your app through the App Store or Ad Hoc
- APNS (Apple Push Notification Service) - You need those to be able to send push notifications to your app. Unlike Development or Distribution certificates, APNS certificates are associated with an App ID. There can be 2 types of APNS certificates, for development - Apple Push Notification service SSL (Sandbox), and for production - Apple Push Notification service SSL (Sandbox & Production). You need to create both of them if you want push notifications to work on both debug and distribution builds.
You can add up to 100 devices per product family per membership year to your account. 100 iPhones, 100 iPads, 100 iPod Touch, 100 Apple Watches and 100 Apple TVs. To add a device to your account, you need to add its unique device ID. You can easily find that in Xcode, or (a bit more complicated) in iTunes. A detailed guide on how to add devices to your account can be found here.
The provisioning profile is what associates an App ID with a certificate and, for development or ad hoc distribution, with some devices. You create the provisioning profiles on the Apple developer portal and you download them in Xcode.
After you have created all these, you can then go to Xcode, add your certificates, refresh your provisioning profiles and then select the provisioning profile you want. You can then select the desired signing identity (based on the certificate associated with it) from that provisioning profile.
Over the years working in iOS development, I’ve asked and I’ve been asked many questions about code signing. Here are some of them.
Q: I have downloaded the provisioning profiles and certificates from the developer portal, but I can’t sign the app.
A: Yes, because you don’t have the private key, the one that was in the certificate signing request. Most likely, another team member created those certificates and provisioning profiles before. You can get the private key from the original developer, revoke the certificate and generate a new one (which will break all provisioning profiles associated with that certificate, but not any App Store apps using those) or create a new one if possible (currently, there’s a maximum of 3 distribution certificates allowed per account).
Q: What about the push certificates? I want my app to receive push notifications. Shouldn’t I create a provisioning profile that uses the APNS certificate?
A: No. When you create an APNS (Apple Push Notification Service) certificate, you associate that with an App ID. So, first you have your CSR, then you create a new APNS certificate with that CSR, download it, open it in Keychain and export it as .p12, which you later upload to your push notification provider. The .p12 file will know that it’s associated with that app, and it will send pushes to that app only. That’s also a reason why you can’t associate an APNS certificate with a wildcard App ID (com.youcompany.*). The push notification server needs to know to which app it sends the notifications.
Q: I bought a new mac, what should I export from the keychain of my old mac for all the code signing to work on the new one?
A: You would probably want all your keychain to be exported to the new mac. You can do that by following these steps. But if you want to export one certificate, make sure you also export its private key. In the Keychain, you have to be able to expand the certificate by pressing on the arrow next to it, and you should see a key. Those certificates are the ones that can be exported as .p12 files. Otherwise, they’ll be exported as .cer, without a private key, and they’ll be pretty much useless.
Q: My iOS distribution certificate expired, will my app still work?
A: When your certificate expires, the provisioning profiles using that certificate will become invalid. On App Store, the app will still work as long as you’re enrolled in the development program. All the ad hoc builds signed with that certificate won’t work anymore.
Q: My APNS certificate expired, what happens now?
A: You won’t be able to send push notifications to the app anymore. This can be fixed by creating a new APNS certificate associated with that App ID, downloading it, exporting its .p12 and uploading it to your push notification service provider. No need for an app update.
The key points I want to highlight about code signing are:
- Each app has an App ID.
- You need to have the private keys for all the certificates you use.
- A debug provisioning profile associates your development certificate with your App ID and the devices.
- An ad hoc provisioning profile associates your distribution certificate with your App ID and the devices.
- An app store provisioning profile associates your distribution certificate with your App ID.
- For push notifications, create an APNS certificate associated with your App ID, then download it, export it as .p12 and upload the .p12 to your push notification service provider; if you want push notifications both on debug and production builds, you have to create 2 APNS certificates, one for development and one for production.
Understanding these will help you understand code signing and save you a lot of time in the end.