Bo2SS

Bo2SS

iOS | Illustrated Principles Behind iOS Signing

image

Last week, I gave a "learning report" to my team, which is actually a weekly technical sharing session where everyone gets a chance to present. This time it was my turn. As a newbie in the team, what should I talk about?

After thinking it over, I suddenly remembered a tricky problem I often encountered: When running an iOS project on a real device, the project hasn't even started, and an error is already reported in the signing configuration (Targets > Signing & Capabilities), regardless of whether it's my own project, a third-party open-source library, or a company project.

Although I could find answers every time I turned to Google or my colleagues, I could only say that I had a vague understanding of why it could be resolved and why signing is necessary for running iOS projects on real devices.

However, I finally understand the secrets behind it! If you have the same confusion, keep reading, and I guarantee you'll thoroughly understand it this time—the principles behind iOS signing!

Article Goals#

By the end of this article, you will have the ability to easily solve the following problems:

  1. How to run your own iOS project or iOS open-source library on a real device?
  2. How to run the company's iOS project on a real device?

Additionally, the ultimate goal of this article is: whenever you encounter any iOS signing-related issues, you can quickly resolve them.

Prerequisite Knowledge: Digital Signatures & Digital Certificates#

Before discussing iOS signing, we first need to understand two prerequisite concepts: signatures ✒️ and certificates 📄 in the internet world.

Refer to: What are digital signatures and digital certificates?——Ruan Yifeng

Digital Signature#

A digital signature is generally embedded in the data to be transmitted to prevent data tampering.

Its underlying core is hash obfuscation algorithms and asymmetric encryption technology (public/private keys).

Generation#

The generation of the signature is performed by the sender in the communication. First, the data to be transmitted is hashed to obtain a data digest. Then, the digest is encrypted with the private key, thus generating the data's signature.

image

Verification#

The receiver receives the data and signature from the sender and processes them as follows:

  • Data: Use the same hash algorithm as the sender to obfuscate the data, obtaining data digest A;
  • Signature: Use the public key corresponding to the private key used by the sender to decrypt the signature, obtaining data digest B.

Compare digest A and digest B; if they are equal, it indicates that the data has not been tampered with; otherwise, there is an issue with the data.

image

The process of generating and verifying the signature is illustrated in the following diagram; analyzing it again can deepen your understanding.

image

Keep the questions in mind:

Q1: Speculate on the process of iOS signing and verification. Among app developers and app users, who is the sender, who is the receiver, and what is the data being transmitted?

A1: The app developer is the sender, the app user is the receiver, and the data being transmitted is the app's installation package.

Q2: How does the receiver obtain the public key used for decryption?

Please continue reading.

Digital Certificate#

Before understanding digital certificates, we might immediately think that the sender could just attach the public key when sending the data and signature, and everything would be ready~ as shown in the diagram below:

image

However, this introduces a new problem:

Q1: How does the receiver confirm that the public key has not been maliciously replaced by someone else? In other words, the identity of the public key is unclear.

This is where digital certificates come into play.

Composition#

Let's first look at the components of a digital certificate, which consists of the public key, the identity information of the public key, and their signature B.

image

Note: The private key used to encrypt the public key data is another public/private key pair, issued by an authoritative certification authority (Certificate Authority, CA).

Public Key Wrapped in a Digital Certificate#

Now, the content sent by the sender has changed from data + signature + public key to data + signature + certificate.

image

The certificate contains the public key needed by the receiver to decrypt signature A, and in addition, the certificate also includes the identity information of the public key and signature B:

  1. The existence of identity information eliminates the risk of unclear public key identity;
  2. And signature B guarantees that the public key and its identity information have not been tampered with.

However, because of signature B, we also need to verify signature B in the certificate before obtaining the public key:

image

Note: The public key used to decrypt the signature B in the certificate is also issued by the CA, which exists in the CA certificate.

Now, I guess you can remember the components of the certificate: public key + identity information of the public key + their signature.

Keep the questions in mind:

Q1: Where does the receiver obtain this CA certificate? How does the receiver verify the signature of this CA certificate? It seems to enter an infinite loop ♻️.

Please continue reading.

Certificate Trust Chain#

CA certificates are generally built-in when installing systems/software, so we should trust them, right~

Next, we can learn about the trust chain of certificates.

Based on the position of the certificate in the trust chain, certificates can be divided into three types:

  • Root Certificate
  • Intermediate Certificate
  • Leaf Certificate

For example: My developer certificate A (Apple Development) is issued by intermediate certificate B (Apple Worldwide Developer Relations Certification Authority, built-in when installing Xcode), intermediate certificate B is issued by root certificate C (Apple Root CA, built-in in the system), and root certificate C is issued by its own CA, as C is at the top of the trust chain, it has the final say.

image

Returning to the previous question: How to ensure that this CA certificate is trustworthy? As long as the receiver has the certificate of the issuer, they can verify it using the public key in the certificate. For example, when an iPhone installs my developed app and receives my developer certificate A, the phone will look for the issuer's certificate B (Apple Worldwide Developer Relations Certification Authority, built into iOS) to verify if A is trustworthy.

Now, you can also check your Mac > Keychain software > Certificates to deepen your understanding.

Continue with the questions:

Q1: Is the CA private key used to encrypt the public key and its identity information located on our local computer? If not, how do we generate our certificate?

Principles of iOS Certificate Application & Application Methods#

Of course not, these private keys are the secret treasures of the CA that issues certificates. For example, if we want to apply for an iOS developer certificate, we need to seek help from Apple, which will use the private key of the intermediate certificate CA mentioned above to issue the certificate.

Application Principles#

To apply for your own iOS developer certificate, the following steps are involved:

  1. Generate a public/private key pair on your computer and fill in the identity information for the key pair;
  2. Send the public key and its identity information to Apple CA;
  3. The CA uses a hash algorithm and the CA private key to sign the data (public key and its identity information), and the data and signature together form the certificate we want;
  4. We then download the certificate to our computer from the CA, and after installing the certificate, the computer will automatically associate it with the corresponding private key.

image

Application Methods: 2 Types#

There are two specific application methods: 1) Uploading a CSR (Certificate Signing Request) file, and 2) Automatic application via Xcode. The second method is recommended.

1) Uploading CSR File Method#

This method is suitable for those who want to understand the principles of iOS certificate application. Note: This method requires joining the Apple Developer Program, $99/year.

a) Open Keychain > Certificate Assistant > Request a Certificate From a Certificate Authority...:

image

b) Enter identity information (email, certificate name), and you can choose to save it locally, which will generate a CSR (.certSigningRequest) file containing the public key and its identity information.

image

You may ask, where is the private key stored? If you are attentive, you will find that in Keychain > login > Keys, there is already a pair of public/private keys you named.

c) Log in to the Apple Developer website, go to the Certificates, Identifiers & Profiles section, upload the CSR file you just generated to create the certificate (.cer file), then download the certificate to your local machine, double-click to import it into Keychain, and you can see the certificate in Keychain > login > My Certificates.

image

If you are attentive, you will find that the certificate in Keychain has already been bound to a private key. If you want to share the certificate with other developers, you need to right-click to export it as a familiar .p12 file, which contains the certificate and the corresponding private key~

This method does not require the cumbersome process of uploading a CSR file and downloading a .cer certificate, nor does it require you to join the Apple Developer Program.

a) Log in to your Apple account in Xcode: Xcode > Preferences > Account > Apple IDs > 「+」。

image

b) After logging in for a moment, you will find that a corresponding certificate has automatically appeared in Keychain.

image

Note: If you have joined the developer program, the Apple Developer website will also automatically add this certificate.

iOS Signing & Packaging Principles#

Finally, we come to the iOS signing part. How well do you understand the previous content? If you are still a bit confused, just remember that the purpose of signing is to prevent the transmitted data from being tampered with, and you will have grasped the essence of this article!

In fact, when signing iOS, it's not just about attaching the certificate (containing the public key); we also need to wrap the certificate in something we are familiar with, which is the Provisioning Profile file, also known as the PP file, description file, or supply configuration file.

PP File#

First, let's understand this important PP file, which we can think of as an upgraded version of the certificate.

How to Generate#

  1. Apply on the developer platform;
  2. Automatically generated by Xcode: Xcode > Targets > Signing & Capabilities > Check Automatically manage signing.

File Structure#

image
  • App ID:
    • Registered on the Apple developer platform; or automatically generated based on the Bundle ID filled in Xcode > Targets > Signing & Capabilities.
    • The Bundle Identifier filled in Xcode > Targets > Signing & Capabilities must match the App ID.
  • Entitlements:
    • A list of allowed permissions; the actual permissions used in the app must be a subset of this list, meaning the capabilities added in Xcode > Targets > Signing & Capabilities cannot exceed this range.
    • There will also be an .entitlements file (authorization file) in the project directory, which is automatically generated based on the capabilities added in Xcode > Targets > Signing & Capabilities. If the app uses a sandbox-restricted feature that is not declared in this .entitlements file, the app will crash when it runs the relevant code.
  • Certificates: Composed of iOS developer certificates, there can be more than one, which are the iOS certificates applied for above.
  • Devices: A list composed of the UDIDs (Unique Device Identifiers) of iOS devices, limiting which iOS devices can develop and debug the app.
  • Signature: When generating the PP file, it is signed by Apple CA to prevent tampering.

Example#

The PP file is saved by default at: ~/Library/MobileDevice/Provisioning\ Profiles.

Below is a preview of a PP file automatically generated by Xcode:

image

Signing & Packaging#

The iOS signing and packaging process is actually controlled by Xcode. See the diagram below:

image

  1. First, Xcode checks whether the bundle ID in the app matches the App ID in the PP file and whether the permissions declared in the app's Entitlements (.entitlements) file are within the range of allowed permissions in the PP file. If either condition is false, the check fails;
  2. Next, Xcode looks in the computer's Keychain for a certificate that matches the Certificates in the PP file. If a match is found, it continues to the next step;
  3. Then, Xcode checks whether the matched certificate is bound to the corresponding private key. If not, the critical step of signing cannot proceed;
  4. Now, it begins to use the hash algorithm and private key to sign the app;
  5. Finally, it packages the app, PP file, and signature, generating the .ipa package.

⚠️: The above ignores the verification process of signature C and signature A. Before using the PP file in step 1 and after matching the certificate in step 2, the CA public key should be used to verify the attached signatures C and A to prevent tampering. If there are any errors, feel free to correct me.

Extended Questions:

Q1: What content will Xcode sign for the app?

A1: All content. However, the signing process is quite complex, and I won't elaborate here. In short, to balance the security and efficiency of signing, the app's signing is divided into 4 hashes and 1 encryption, with each hash being interconnected, ensuring that the app content has not been tampered with.

image

For more details, refer to Detailed Explanation of iOS Code Signing (Part 3): The Signing Process and Data Structure of Code Signing.

iOS Verification Principles#

After discussing iOS signing, how does the real device verify the app's signature during installation?

First, we need to know that app installation packages are divided into test packages and official packages, and the verification processes for the two are different.

Additionally, here’s some knowledge about test packages and official packages:

  1. Test packages: These include internal test packages, release packages prepared for App Store upload, Ad Hoc release packages, and In-house enterprise internal release packages.
  2. Official packages: Installation packages uploaded to the App Store.

⚠️: Packages built by Xcode are all considered test packages.

Refer to Introduction to Different Types of iOS Test Packages——Sogou Testing Official Account.

Test Packages#

When installing test packages, the real device performs a complete verification process, as shown in the diagram below:

image

  1. First, the real device uses the system's built-in CA public key to verify the PP file and its signature C's legality;
  2. Next, the real device uses the system's built-in CA public key to verify the certificate in the PP file and its signature A's legality; (The app stores the certificate information used to generate signature B, allowing the real device to know which certificate's public key to retrieve)
  3. Then, the real device retrieves the public key from the certificate to verify the app and its signature B's legality;
  4. Finally, the real device checks whether its UDID is in the Devices list of the PP file. If it exists, the app installation begins.

⚠️: The diagram simplifies the verification process. I believe you are already familiar with this process: hash obfuscation, public key decryption, equality check...

In fact, the signature verification is not completed in one go; it has different verification rules during installation, startup, and runtime. The above process is simplified; for more details, refer to Detailed Explanation of iOS Code Signing (Part 4): Signature Verification, Jailbreaking, and Resigning.

Official Packages#

When installing official packages, the verification process is greatly simplified because the verification of the developer certificate is handled by the App Store.

  1. Upload the release package to the App Store.

image

  1. When you upload the release package (a type of test package) to the App Store, Apple will also verify the release package, and the process is similar to the verification process for the above test package;
  2. After verification, the App Store will re-sign the app. Here, the private key corresponding to the developer certificate is not used, but the CA private key is used;
  3. Finally, the App Store will only package the app and the new signature, generating the .ipa package. (⚠️: The PP file is not included)
  1. The real device installs the official package.

image

When the device downloads the app from the App Store, it only needs to use the system's built-in CA public key to verify the app. If the verification passes, it can be installed.

Practice#

There are also some well-drawn diagrams online that you can review in order to reinforce the content of this article.

image

From iOS Certificates and Related Matters——Juejin.

image

From The Principles of iOS App Signing——Blog.

Returning to: Article Goals#

Finally, let's return to the questions posed at the beginning of the article. To solve those problems, always remember two things: the certificate containing the private key (.p12 = .cer + private key) and the PP file (.mobileprovision).

Now, looking at our questions, as long as we find the above two items, we can resolve them:

  1. How to run your own iOS project or iOS open-source library on a real device?
    1. Certificate containing the private key: Refer to the section on iOS certificate application methods;
    2. PP file: Apply on the developer platform; or automatically generated by Xcode, Targets > Signing & Capabilities > Check Automatically manage signing.
  2. How to run the company's iOS project on a real device?
    1. Certificate containing the private key: Request from the team, noting that the file extension is .p12;
    2. PP file: Request from the team, and remember to ask the person in charge to add your real device's UDID to the PP file on the developer platform.

PS:

  • When running the app installed from a test package, you generally also need to trust the certificate on the real device: Settings > General > VPN & Device Management.
  • Xcode automatically generates the PP file:

image

References#

Overall grasp: The Principles Behind iOS Certificates——Blog

In-depth understanding: Detailed Explanation of iOS Code Signing——Blog

Other resources you might be interested in:

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.