Requirements For Trusted Certificates In Ios Ssl Certificate Validation

In this tutorial, you’ll learn how to prevent man-in-the-middle attacks using SSL Pinning and Alamofire. You’ll use the Charles Proxy tool to simulate the man-in-the-middle attack.

Đang xem: Ios ssl certificate validation

*

*

Nowadays, most iOS apps communicate with a server to retrieve information to work with. When apps exchange information, they typically use the Transport Layer Security (TLS) protocol to provide secure communications.

Apps don’t usually determine which certificates to trust and which not to trust when they try to establish a connection with a server. Rather, they rely entirely on the certificates that iOS contains.

Even if TLS protects the transmitted data against eavesdropping and tampering, attackers can set up man-in-the-middle attacks using hacked or self-signed certificates. Through these certificates, they can capture data moving to and from your app.

In this tutorial, you’ll learn how to prevent man-in-the-middle attacks using SSL Certificate Pinning and Alamofire 5. To verify that your implementation works as expected, you’ll use Charles Proxy‘s man-in-the-middle strategy.

Note: Secure Sockets Layer (SSL) is the ancestor of TLS. TLS addresses various security vulnerabilities identified by Internet Engineering Task Force (IETF) which affected SSL version 3.0. Throughout this tutorial, you should read SSL and TLS as synonyms, but code implementation should always use TLS.

Getting Started

For this tutorial, you’ll use PinMyCert, an iOS app that uses the Stack Exchange REST API to retrieve Stack Overflow users.

Start by downloading the starter project using the Download Materials button at the top or bottom of this tutorial. Once downloaded, open PinMyCert.xcodeproj in Xcode.

To keep you focused, the starter project has everything unrelated to SSL Certificate Pinning already set up for you.

Open Main.storyboard and look at the view controllers contained within. The view controller on the left is the root navigation controller of the app. Next, you have ViewController, which includes a table that lists the users retrieved from Stack Overflow. Finally, you have DetailViewController, which displays the detail for the selected user.

ViewController uses NetworkClient. This is a wrapper around Alamofire which exposes an API that performs network requests. In NetworkClient, you’ll implement the logic for dealing with SSL Certificate Pinning. More on that later.

Build and run the app, and you’ll see this initial screen:

*

Before diving directly into the code, let’s talk about TLS!

Understanding TLS

*

Public key plus private key equals…

To understand SSL Certificate Pinning, you should first grasp the essence of TLS and its cryptographic underpinnings.

The main goal of TLS is to add privacy and integrity to messages exchanged between two parties. In other words, TLS allows you to transmit data over a network without exposing that data to untrusted third parties.

When a client and a server need a TLS connection, building that connection follows three phases, executed in a specific order.

*

The Three Phases of TLS Connections

In the first phase, the client initiates a connection with the server.

The client then sends the server a message, which lists the versions of TLS it can support along with the cipher suite it can use for encryption.

Note: A cipher suite is a set of algorithms that you need to secure a network connection through TLS. For more info, please refer to cipher suite.

The server responds with the selected cipher suite and sends one or more digital certificates back to the client.

The client verifies that those digital certificates — certificates, for short — are valid. It also verifies that the server is authentic and not someone who wants to snoop sensitive information.

Read More:  Borderlands 3: Three Sims Are Better Than One Borderlands 3 9;S Dedication

If the validation succeeds, the second phase of verification begins. The client generates a pre-master secret key and encrypts it with the server’s public key — i.e., the public key included in the certificate.

The server receives the encrypted pre-master secret key and decrypts it with its private key. The server and client each generate the master secret key and session keys based on the pre-master secret key.

Note: The second phase uses public-key cryptography or asymmetric cryptography. This is a cryptographic system that uses pairs of keys: Public keys, which are widely disseminated and private keys, which only the owner knows.

That master secret key is then used in the last phase to decrypt and encrypt the information that the two actors exchange.

Note: The third phase uses symmetric-key cryptography, where you use the same key for both encryption of plaintext and decryption of ciphertext.

About Digital Certificates

As you’ve learned in the previous section, the server sends one or more certificates back to the client.

So, what’s a certificate? A certificate is a file that encapsulates information about the server that owns the certificate. It’s similar to an identification card, such as a passport or a driver license.

A Certificate Authority (CA) can issue a certificate or it can be self-signed. In the first case, the CA must validate the identity of the certificate holder both before it issues the certificate and when your app uses the certificate. In the second case, the same entity whose identity it certifies signs the certificate.

The Structure of a Digital Certificates

The structure of a certificate uses X.509 standard. Here are the main fields:

Subject: Provides the name of the entity (computer, user, network device, etc.) that the CA issued the certificate to.Serial Number: Provides a unique identifier for each certificate that a CA issues.Issuer: Provides a unique name for the CA that issued the certificate.Valid From: Provides the date and time when the certificate becomes valid.Valid To: Provides the date and time when the certificate is no longer considered valid.

Xem thêm: Template: Server Checklist Template Excel, Server Preventive Maintenance Checklist Template

Public Key: Contains the public key of the key pair that goes with the certificate.Algorithm Identifier: Indicates the algorithm used to sign the certificate.

The couple consisting of the public key and the algorithm identifier represents the subject public key info.

*

X.509 certificates can be encoded differently, which will affect their appearance. The most common are:

Validating Digital Certificates

When you get a certificate from a CA, that certificate is part of a chain of trust, or a chain of certificates.

The number of certificates in the chain depends on the CA’s hierarchical structure. The two-tier hierarchy is the most common. An issuing CA signs the user’s certificate and a root CA signs the issuing CA’s certificate. The root CA is self-signed and the app must trust it at the end.

*

During a certificate validation, the app verifies:

The date of evaluation, which must fall between the Valid From and Valid To fields of the certificate for the certificate to be valid.The digital signature, by finding the public key of the next issuing CA or intermediate CA. The process continues until it reaches the root certificate.
Note: iOS keeps all well-known root CA certificates in its Trust Store. If you want to know the trusted root certificates that come pre-installed with iOS, please refer to Apple’s lists of available trusted root certificates in iOS.

SSL Certificate Pinning Under the Hood

SSL Certificate Pinning, or pinning for short, is the process of associating a host with its certificate or public key. Once you know a host’s certificate or public key, you pin it to that host.

Read More:  Visit An Oversized Phone A Big Piano And A Giant Dancing Fish Trophy

In other words, you configure the app to reject all but one or a few predefined certificates or public keys. Whenever the app connects to a server, it compares the server certificate with the pinned certificate(s) or public key(s). If and only if they match, the app trusts the server and establishes the connection.

You usually add a service’s certificate or public key at development time. In other words, your mobile app should include the digital certificate or the public key within your app’s bundle. This is the preferred method, since an attacker cannot taint the pin.

Why Do You Need SSL Certificate Pinning?

Usually, you delegate setting up and maintaining TLS sessions to iOS. This means that when the app tries to establish a connection, it doesn’t determine which certificates to trust and which not to. The app relies entirely on the certificates that the iOS Trust Store provides.

This method has a weakness, however: An attacker can generate a self-signed certificate and include it in the iOS Trust Store or hack a root CA certificate. This allows such an attacker to set up a man-in-the-middle attack and capture the transmitted data moving to and from your app.

Restricting the set of trusted certificates through pinning prevents attackers from analyzing the functionality of the app and the way it communicates with the server.

Types of SSL Certificate Pinning

If you want to implement pinning — which it seems you do, since you’re reading this tutorial — you can decide between two options:

Pin the certificate: You can download the server’s certificate and bundle it into your app. At runtime, the app compares the server’s certificate to the one you’ve embedded.Pin the public key: You can retrieve the certificate’s public key and include it in your code as a string. At runtime, the app compares the certificate’s public key to the one hard-coded in your code.

Choosing between these two options depends on your needs and server configuration. If you choose the first option, you need to upload your app when your server rotates (changes) its certificate or it will stop working. If you choose the second option, it may violate key rotation policy because the public key doesn’t change.

Note: As well as pinning the certificate or the public key, it’s also possible to pin the subject public key info. At the time of this writing, Alamofire is not able to perform this type of pinning. If you’re looking for such a solution, refer to TrustKit.

Now that you have a solid grasp on how pinning works, it’s time to see what Alamofire 5 can do for you!

Pinning in Alamofire 5

Alamofire 5 supports the pinning of both the certificate and the public key. In particular, it provides two different classes, called respectively PinnedCertificatesTrustEvaluator and PublicKeysTrustEvaluator, which allow you to deal with these cases.

Note: Hereafter, this tutorial will only cover certificate pinning. You can play around with the implementation of public key pinning once you’ve finished the tutorial, if you want to.

Storing The Certificate

To see Alamofire 5 in action, first you need to download the certificate from StackExchange.com.

Use OpenSSL to retrieve the certificate from the Stack Overflow server. More specifically, you’ll use the s_client command, which can connect to any server over SSL by specifying the server address and port 443.

Open a new Terminal and type cd followed by a space. Then, drag and drop the directory of the starter project that you downloaded in the Getting Started section and press Enter on your keyboard.

Read More:  International Journal Of Project Management Articles 2018, International Journal Of Project Management

*

Still in the terminal window, type cd PinMyCert to move into your project’s root folder.

Next, copy and paste the following snippet:

openssl s_client -connect api.stackexchange.com:443 Once it completes, you”ll receive a lot of data including a list of certificates. Each certificate in the chain has a Common Name (CN).

Certificate chain 0 s:/C=US/ST=NY/L=New York/O=Stack Exchange, Inc./CN=*.stackexchange.com i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CABelow that, you can see the actual certificate you”re interested in, which is the one where CN is *.stackexchange.com.

Server certificate—–BEGIN CERTIFICATE—–MIIHMjCCBhqgAwIBAgIQBmgM1QeOzDnM9C33n9PrfTANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIFNlcnZlciBDQTAeFw0xNjA1MjEwMDAwMDBaFw0xOTA4MTQxMjAwMDBaMGoxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJOWTERMA8GA1UEBxMITmV3IFlvcmsxHTAbBgNVBAoTFFN0YWNrIEV4Y2hhbmdlLCBJbmMuMRwwGgYDVQQDDBMqLnN0YWNrZXhjaGFuZ2UuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr0YDzscT5i6T2FaRsTGNCiLB8OtPXu8N9iAyuaROh/nS0kRRsN8wUMk1TmgZhPuYM6oFS377V8W2LqhLBMrPXi7lnhvKt2DFWCyw38RrDbEsM5dzVGErmhux3F0QqcTI92zjVW61DmE7NSQLiR4yonVpTpdAaO4jSPJxn8d+4p1sIlU2JGSk8LZSWFqaROc7KtXtlWP4HahNRZtdwvL5dIEGGNWx+7B+XVAfY1ygc/UisldkA+a3D2+3WAtXgFZRZZ/1CWFjKWJNMAI6ZBAtlbgSNgRYxdcdleIhPLCzkzWysfltfiBmsmgz6VCoFR4KgJo8Gd3MeTWojBthM10SLwIDAQABo4IDzDCCA8gwHwYDVR0jBBgwFoAUUWj/kK8CB3U8zNllZGKiErhZcjswHQYDVR0OBBYEFFrBQmPCYhOznZSEqjIeF8tto4Z7MIIB/AYDVR0RBIIB8zCCAe+CEyouc3RhY2tleGNoYW5nZS5jb22CEXN0YWNrb3ZlcmZsb3cuY29tghMqLnN0YWNrb3ZlcmZsb3cuY29tgg1zdGFja2F1dGguY29tggtzc3RhdGljLm5ldIINKi5zc3RhdGljLm5ldIIPc2VydmVyZmF1bHQuY29tghEqLnNlcnZlcmZhdWx0LmNvbYINc3VwZXJ1c2VyLmNvbYIPKi5zdXBlcnVzZXIuY29tgg1zdGFja2FwcHMuY29tghRvcGVuaWQuc3RhY2thdXRoLmNvbYIRc3RhY2tleGNoYW5nZS5jb22CGCoubWV0YS5zdGFja2V4Y2hhbmdlLmNvbYIWbWV0YS5zdGFja2V4Y2hhbmdlLmNvbYIQbWF0aG92ZXJmbG93Lm5ldIISKi5tYXRob3ZlcmZsb3cubmV0gg1hc2t1YnVudHUuY29tgg8qLmFza3VidW50dS5jb22CEXN0YWNrc25pcHBldHMubmV0ghIqLmJsb2dvdmVyZmxvdy5jb22CEGJsb2dvdmVyZmxvdy5jb22CGCoubWV0YS5zdGFja292ZXJmbG93LmNvbYIVKi5zdGFja292ZXJmbG93LmVtYWlsghNzdGFja292ZXJmbG93LmVtYWlsghJzdGFja292ZXJmbG93LmJsb2cwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzUuY3JsMDSgMqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzUuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMIGDBggrBgEFBQcBAQR3MHUwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBNBggrBgEFBQcwAoZBaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkhpZ2hBc3N1cmFuY2VTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEARIdUz7n08ZtqWscAmTXegtB6yPrU0l5IQCXQRqnEVXPKyS+w8IVOcblTT/W2Qlp5we2BTDbRDfVokXIOSxOTAT0XN3f3c+nbvKJ3XMBH236846AY6bpfqL0/05gcdt39d2iXTL+qnJW9P0yFKpkfGXBBTYQl4ACSeThSuSBXIVJ0v/TfR9+ggXuPpmXiIKkPOReKu2Tu8SO7+5KRqRJvYhP9mhL4Bl+YLrTQXzM1NwVAahRT1QJJNemyyEY1kkZOCKt0xRu4CVWhJlpNdoRZenT9BrD8Fo22kt5MxAvCVrjT/g1BHDQd4S8pPKC8kRwmMA8mdo8TiHJQMy0DBCDCDg==—–END CERTIFICATE—–subject=/C=US/ST=NY/L=New York/O=Stack Exchange, Inc./CN=*.stackexchange.comissuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CATo copy the certificate into a file, use openssl again. Repeat the previous command and pass its output to openssl x509, specify DER encoding and output it to a new file named stackexchange.com.der:

openssl s_client -connect api.stackexchange.com:443 If you”ve followed the steps correctly, you should be able to see that certificate in the same folder of your project.

*

Implementing Certificate Pinning

Before writing the code, you need to import the certificate that you previously downloaded. Open PinMyCert.xcodeproj in Xcode, if you don”t still have it open.

Right-click on the root PinMyCert folder in the Project navigator. Click Add Files to “PinMyCert”…, then in the file chooser, find and select stackexchange.com.der and click Add.

*

Open NetworkClient.swift and paste the following code at the end of the file:

struct Certificates { static let stackExchange = Certificates.certificate(filename: “stackexchange.com”) private static func certificate(filename: String) -> SecCertificate { let filePath = Bundle.main.path(forResource: filename, ofType: “der”)! let data = try! Data(contentsOf: URL(fileURLWithPath: filePath)) let certificate = SecCertificateCreateWithData(nil, data as CFData)! return certificate }}The above struct provides a user-friendly way to retrieve a certificate from the main bundle.

SecCertificateCreateWithData is responsible for creating a certificate object from a DER-encoded file.

Still within NetworkClient.swift, find NetworkClient and replace the entire line let session = Session.default with the following code:

// 1let evaluators = < "api.stackexchange.com": PinnedCertificatesTrustEvaluator(certificates: < Certificates.stackExchange >)>let session: Session// 2private init() { session = Session( serverTrustManager: ServerTrustManager(evaluators: evaluators) )}Here”s the breakdown of the code above:

You create a dictionary called evaluators, which contains a single key-value pair. The key is of type String and it represents the host you want to check. The value is of a subtype of ServerTrustEvaluating called PinnedCertificatesTrustEvaluator. It describes the evaluation policy you want to apply for that specific host. You”ll use the PinnedCertificatesTrustEvaluator to validate the server trust. The server trust is valid if the pinned certificate exactly matches the server certificate.You declare a private initializer that instantiates Session using ServerTrustManager. The latter is responsible for managing the mapping declared in the evaluators dictionary.

Now, open ViewController.swift and find the code responsible for the network request:

NetworkClient.request(Router.users) .responseDecodable { (response: DataResponse) in switch response.result { case .success(let value): self.users = value.users case .failure(let error): self.presentError(withTitle: “Oops!”, message: error.localizedDescription) }}Replace it with this new implementation:

NetworkClient.request(Router.users) .responseDecodable { (response: DataResponse) in switch response.result { case .success(let value): self.users = value.users case .failure(let error): let isServerTrustEvaluationError = error.asAFError?.isServerTrustEvaluationError ?? false let message: String if isServerTrustEvaluationError { message = “Certificate Pinning Error” } else { message = error.localizedDescription } self.presentError(withTitle: “Oops!”, message: message) }}While the success case remains the same, you have enriched the failure case with an additional condition. First, you try to cast error as an AFError. If the cast succeeds, you”ll evaluate isServerTrustEvaluationError. If its value is true, it means the certificate pinning has failed.

Xem thêm: Reasons To Upgrade To Windows 10, Why Your Business Should Upgrade To Windows 10

Build and run the app. Nothing should have changed visually.

But wait! If this is a tutorial that teaches you how to prevent man-in-the-middle attacks, how can you be sure you”ve done everything correctly when no attack has occurred?

Leave a Reply

Your email address will not be published. Required fields are marked *