iOS Code Signing: Under The Hood

This is a guest post by Adam Eberbach, a mod on the forums and a full-time iOS developer in Melbourne, Australia for Intunity, a local consultancy. Many beginner iOS developers cringe when they think about bundle identifiers, provisioning profiles, App IDs, or certificate signing requests. It’s a lot of new and confusing terminology coming all […] By Ray Wenderlich.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 3 of this article. Click here to view the first page.

Public and Private Keys, Oh My!

Before we continue with the explanation of how things work, let’s briefly explain public and private keys.

There are two different types of cryptography: symmetric cryptography, and asymmetric cryptography.

With symmetric cryptography, there’s only one key. So if you have a secret key and encrypt a message with it, only a person who knows the secret key can decrypt it.

In asymmetric cryptography, there are two keys - a public key (which can be known by everyone) and a private key (which is kept secret to you).

One of the nice things about asymmetric cryptography is that you can use to prove a message came from you. If you encrypt something with your secret private key and someone can decrypt the message with your public key to get something that makes sense, they know that you, being the only person who knows the private key, created the message.

In other words, it is “signed”. And this is the basic technique behind code signing apps in iOS!

This is all you really need to know about code signing to understand how things work at a high level for the rest of this article. But if you’re curious to learn more, Wikipedia and RSA Labs have articles that explain this concept in much more detail. And if you really get interested in how it works read Bruce Schneier.

Code Signing Objects

There are a lot of objects related to Code Signing - Provisioning Profiles, App IDs, UDIDs, and more. In this section we’ll go through what each of these mean, one by one.

I’ve also put together a diagram using the Core Data model editor to help show the relationships between the objects, shown below. Refer back to this as we go through each object, so you can understand how they all fit together. This diagram is for development profiles - for Distribution it is very slightly different, and that will be covered in a future article.

Objects related to Code Signing

Without further ado, let’s discuss these in more detail, starting with a more about private keys!

Private Key

In Mac OS X keys are managed through an app called Keychain Access found in Applications\Utilities. Go ahead and run it now - you might see a private key and a public key with your name attached similar to the following:

Keychain Access showing public/private keys

Notice that the private key shows certificates that it has been used to sign - in this case the developer certificate.

If you don’t have any keys listed here yet don’t worry, Keychain Access will create one for you the first time you request a certificate (which we’ll talk about later).

The keys that are listed here (or that will be listed here soon) are the foundation of all your provisioning and code signing abilities. Without them, you can’t sign your code or release your apps to the App Store!

If you lose them you have to start the whole process again - your certificates will not work any more, your provisioning profiles will generate only errors, you will waste a lot of time - so keep them safe.

So if you haven’t already, export these now by going to File\Export Items, and saving them to a safe place. I suggest using a small thumb drive that you can put in a safe place and use for nothing else. You also might consider syncing to Mobile Me if you have an account.

Have Multiple Keys?

If you have created accounts on several Macs without knowing about this key pair then you likely have several. This can be a problem because the certificate you generate on one machine will not be usable for code signing on a machine that does not have that private key. Forgetting this is a great way to waste hours and get angry...

You could propagate all your keys to all your machines but I prefer to maintain just one. I like to have just one key pair for everything and I have been able to delete extra keys, in fact all keys, with no bad effect - the worst thing that happened to me was I had to sign in to a couple of websites again.

If you choose to keep just one pair of keys you should name them so your one true key is easier to track - by default they are all named the same. To rename you have to double-click them in Keychain Access, type a new name and close the dialog.

UDID

A UDID is a unique identifier for each physical device. So your iPhone is guaranteed to have a different UDID than your iPad, for example. It is usually displayed as a 40-character hexadecimal string.

When you want to get code on a device through means other that the app store or enterprise distribution (wait for part 2 of this article series) this is the way you identify each device that your code is signed to run on. So if you want to install an app you make on a device, you need to know that device’s UDID!

But how can you find a device’s UDID? There are several ways.

First, when a device is connected to your PC you can find the UDID in the Xcode Organizer window as shown below:

How to see your device's UDID in XCode Organizer

Second, you can see the UIDID in iTunes clicking the serial number displayed in the Summary screen - useful to know when you have someone who wants your app on their device but does not have Xcode.

How to find a device's UDID in iTunes

Third and finally, I’ve found the easiest method to get a client or customer to send you their UDID is to have them download an app called Ad Hoc Helper on the App Store.

Ad Hoc Helper is a simple app that on startup begins an email that includes the device’s UDID, and the client or customer can send the email to you so you have it - with no typos!

Certificates

The certificate, whether your personal developer certificate or the grandly-named “Apple Worldwide Developer Relations Certification Authority Certificate”, are bundles of data that represent trust. They are the guarantee that you, the named developer, built this code, that you are a member of the developer program, and that Apple have issued you with a certificate to do so.

To get a certificate, you need to generate a Certificate Signing Request with Keychain Access and send it to Apple. As mentioned earlier, this will create a public/private key for you if you don’t have one already. Apple will then verify the information, and create a certificate for you.

App ID

When you create a project in Xcode 4, you are asked for a Product Name and Company Identifier. For the product name, you usually give a shortened version of your app (such as myapp), and for the company identifier you usually give a unique string for your company (reverse DNS notation works well, such as com.mycompanyname).

These combine to form the Bundle Identifier, found in the “-Info.plist” file in your project, as you can see below:

Finding the Bundle Identifier in your Info.plist

An App ID is simply this same Bundle identifier here, along with a prefix of random characters. It looks something like “ESCSR39CF9.com.AwesomeAppCo.Alabasteroids” forming a unique identifier for your application.

(I’m not actually writing a masonry-based space shooter right now so feel free to steal the name.)

For every app you release, you need to register your App ID in the iTunes Developer Center as shown in the screenshot below, and it needs to match what you have set in your Info.plist.

Provisioning Profile

When put together all these objects combine so that:

  • this unique app (App ID)
  • can run on this restricted set of devices (UDIDs)
  • with trust based on the signing by a developer (Certificate).

And the combination of these three pieces of info is called a provisioning profile!

A provisioning profile accompanies the device either by being copied into Xcode or iTunes and from there onto the device, or by being part of a “.ipa” archive containing both app and profile.

You can make a Provisioning Profile in the iOS Provisioning Portal, as shown in the screenshot below:

Creating a Provisioning Profile in the iOS Provisioning Portal

When setting one up, you have to do the following:

  • You need to give the profile a name, which is the name you will see in the Xcode Organizer, Build Settings and other places.
  • You need to select all the certificates that will be able to build using this provisioning profile - if working in a team there is no harm in selecting everyone.
  • You need to select the App ID, which needs to match what is set up in your Info.plist.
  • Finally, you need to specify which UDIDs this profile applies to. Generally I select all the devices for which I have UDIDs, I have sometimes wished I had more UDIDs in a profile but never less.

Contributors

Over 300 content creators. Join our team.