قالب وردپرس درنا توس
Home / IOS Development / Prevent man-in-center attacks in IOS with SSL Pinning

Prevent man-in-center attacks in IOS with SSL Pinning



Today, most iOS apps communicate with a server to retrieve information to work with. When applications exchange information, they usually use Transport Layer Security (TLS) protocol to provide secure communication.

Apps usually do not determine which certificates to trust and which ones should not trust when trying to establish a connection with a server. Instead, they completely rely on the certificates that IOS contains.

Although TLS protects transmitted data from eavesdropping and manipulation, attackers can set up man-in-center attacks using hacked or self-signed certificates. Through these certificates, they can capture data that is moved to and from your app.

In this tutorial you will learn how to prevent attacks between people in the middle using SSL Certificate Stick and ] Alamofire 5 . To confirm that the implementation works as expected, use Charles Proxy s man-in-center strategy.

Note : Secure Sockets Layer (SSL) are ancestors of TLS. TLS addresses various security issues identified by the Internet Engineering Task Force (IETF) that affected SSL version 3.0. Through this tutorial, you should read SSL and TLS as synonyms, but code implementation should always use TLS .

Getting Started

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

Start downloading the start project with the button Download materials at the top or bottom of this tutorial. After downloading, open PinMyCert.xcodeproj in Xcode.

To keep you focused, the start-up project has no connection to SSL certificate Pinning already set up for you.

Open Main.storyboard and look at the display controls contained in. The display controller on the left is the root navigation control for the app. Then you have ViewController that contains a table showing the users retrieved from Stack Overflow. Finally, you have DetailViewController showing the details of the selected user.

ViewController uses NetworkClient . This is a wrapper around Alamofire that reveals an API that performs network requests. In NetworkClient you will implement the logic to handle SSL certificate Pinning. More on that later.

Build and run the app and you will see this home screen:

 Initial Screen

Before diving directly into the code, let's talk about TLS! [19659015] Understanding TLS

  Off to TLS lab!

Public key plus private key is similar …

To understand SSL certificate stick, first understand the essence of TLS and its cryptographic data.

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

When a client and a server need a TLS connection, this connection builds three phases, executed in a particular order. [19659002]   TLS Handshake

The three phases of the TLS connection

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

The client then sends the server a message showing versions of TLS that can support along with the encryption package that can be used for encryption.

Note : An encryption package is a set of algorithms that you need to secure a network connection via TLS. For more information, see the encryption package.

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

The client confirms that these digital certificates – certificates, for cards – are valid. It also confirms that the server is authentic and not someone who wants to sneak sensitive information.

If the validation succeeds, the second phase of the verification begins. The client generates a pre-master secret key and encrypts it with the server's public key – that is, the public key included in the certificate.

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

Note : The second phase uses public key encryption or asymmetric cryptography . This is a cryptographic system that uses keys: Public keys, which are wide spread and private keys, which only the owner knows.

This master secret key is then used in the last phase to decrypt and encrypt the information as

: The third phase uses symmetric key cryptography using the same key for both plain text encryption and encryption text decryption .

About Digital Certificates

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

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

A certificate authority (CA) may issue a certificate or it may be self-signed. In the first case, the CA must validate the identity of the certificate holder, both before issuing the certificate and when your app is using the certificate. In the second case, the same entity whose identity it certifies will sign the certificate.

The structure of a digital certificate

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

  • Subject : Enter the name of the device (computer, user, network device, etc.) to which the CA issued the certificate.
  • Serial number : Provides a unique identifier for each certificate that a CA issues.
  • Issuer : Provides a unique name to 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.
  • Public key : Contains the public key for the key pair that comes with the certificate.
  • Algorithm Identifier : Specifies the algorithm used to sign the certificate.
  • Digital Signature : A small string used to verify the authenticity of the certificate.

The pair consisting of the public key and the algorithm identifier represent the topic of public key information . [19659002]   X.509 Digital Certificate

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

Digital Certificate Validation

When you get a certificate from a CA, the certificate is part of a trust set or certificate chain.

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 certificate. The root CA is self-signed and the app must rely on it at the end.

 Chain of Trust

During a certification validation, the app confirms:

  • The evaluation date that must fall between Valid from and Valid to field in the certificate for the certificate to be valid.
  • The digital signature, by finding public key for the next issuing CA or intermediate CA. The process continues until it reaches the root certificate.

SSL certificate stick under the cap

The SSL certificate stick, or card shortcut, is the process of associating a host with a certificate or public key. When you know a host's certificate or public key, pin it to the host.

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

Usually you add a service certificate or a public key at development time. In other words, your mobile app should contain the digital certificate or public key in the app bundle. This is the preferred method since an attacker cannot clog the stick.

Why do you need an SSL certificate stick?

Usually, you delegate the setup and maintenance of TLS sessions to iOS. This means that when the app tries to establish a connection, it does not determine which certificates to trust and which ones should not. The app depends entirely on the certificates offered by the iOS Trust Store.

This method has a weakness, but: 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-center attack and capture the transmitted data to and from your app.

Limiting the set of trusted certificates by 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 – as you think, since you are reading this tutorial – you can decide between two options:

  • Point the certificate : You can download the server's certificate and pack it into your app. At runtime, the app compares the server's certificate with the one you have built-in.
  • Point to 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 encoded in your code.

Choosing between these two options depends on your needs and server configuration. If you select the first option, you need to upload your app when the server rotates (changes) the certificate, or it will stop working. If you choose the second option, it may be contrary to the key rotation policy because the public key is not changed.

Note : In addition to putting the certificate or public key in place, it is also possible to point to public topic info. At the time of this writing, Alamofire cannot perform this type of pinning. If you're looking for such a solution, see the TrustKit.

Now that you have a solid understanding of how pinning works, it's time to see what Alamofire 5 can do for you!

Pinning in Alamofire 5 [19659007] Alamofire 5 supports the fastening of both the certificate and the public key. In particular, it provides two different classes, called PinnedCertificatesTrustEvaluator and respectively, PublicKeysTrustEvaluator which allow you to handle these issues.

Note : Hereafter, this tutorial will only cover certificate stick. You can play with the implementation of the publishing key when you finish the tutorial, if you want.

Save the certificate

To view Alamofire 5 in progress, you must first download the certificate from StackExchange.com .

Use OpenSSL to retrieve the certificate from the Stack Overflow server. More specifically, you will use the s_client command that 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 start project directory you downloaded into the Getting Started section and press Type on the keyboard.

 Change directory [19659002] Continue in the terminal window, type cd PinMyCert to move into the root folder of the project folder.

Next, copy and paste the following excerpts:

  openssl s_client-connect api.stackexchange.com: 443 </ dev / null

Once completed, you will 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 CA

Below you can see the actual certificate you are interested in, which is where CN is *. Stackexchange.com .

  Server certificate
----- BEGIN CERTIFICATE -----
MIIHMjCCBhqgAwIBAgIQBmgM1QeOzDnM9C33n9PrfTANBgkqhkiG9w0BAQsFADBw
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz
dXJhbmNlIFNlcnZlciBDQTAeFw0xNjA1MjEwMDAwMDBaFw0xOTA4MTQxMjAwMDBa
MGoxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJOWTERMA8GA1UEBxMITmV3IFlvcmsx
HTAbBgNVBAoTFFN0YWNrIEV4Y2hhbmdlLCBJbmMuMRwwGgYDVQQDDBMqLnN0YWNr
ZXhjaGFuZ2UuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr0YD
zscT5i6T2FaRsTGNCiLB8OtPXu8N9iAyuaROh / nS0kRRsN8wUMk1TmgZhPuYM6oF
S377V8W2LqhLBMrPXi7lnhvKt2DFWCyw38RrDbEsM5dzVGErmhux3F0QqcTI92zj
VW61DmE7NSQLiR4yonVpTpdAaO4jSPJxn8d + 4p1sIlU2JGSk8LZSWFqaROc7KtXt
lWP4HahNRZtdwvL5dIEGGNWx + 7B + XVAfY1ygc / UisldkA + a3D2 + 3WAtXgFZRZZ / 1
CWFjKWJNMAI6ZBAtlbgSNgRYxdcdleIhPLCzkzWysfltfiBmsmgz6VCoFR4KgJo8
Gd3MeTWojBthM10SLwIDAQABo4IDzDCCA8gwHwYDVR0jBBgwFoAUUWj / kK8CB3U8
zNllZGKiErhZcjswHQYDVR0OBBYEFFrBQmPCYhOznZSEqjIeF8tto4Z7MIIB / Ayd
VR0RBIIB8zCCAe + CEyouc3RhY2tleGNoYW5nZS5jb22CEXN0YWNrb3ZlcmZsb3cu
Y29tghMqLnN0YWNrb3ZlcmZsb3cuY29tgg1zdGFja2F1dGguY29tggtzc3RhdGlj
Lm5ldIINKi5zc3RhdGljLm5ldIIPc2VydmVyZmF1bHQuY29tghEqLnNlcnZlcmZh
dWx0LmNvbYINc3VwZXJ1c2VyLmNvbYIPKi5zdXBlcnVzZXIuY29tgg1zdGFja2Fw
cHMuY29tghRvcGVuaWQuc3RhY2thdXRoLmNvbYIRc3RhY2tleGNoYW5nZS5jb22C
GCoubWV0YS5zdGFja2V4Y2hhbmdlLmNvbYIWbWV0YS5zdGFja2V4Y2hhbmdlLmNv
bYIQbWF0aG92ZXJmbG93Lm5ldIISKi5tYXRob3ZlcmZsb3cubmV0gg1hc2t1YnVu
dHUuY29tgg8qLmFza3VidW50dS5jb22CEXN0YWNrc25pcHBldHMubmV0ghIqLmJs
b2dvdmVyZmxvdy5jb22CEGJsb2dvdmVyZmxvdy5jb22CGCoubWV0YS5zdGFja292
ZXJmbG93LmNvbYIVKi5zdGFja292ZXJmbG93LmVtYWlsghNzdGFja292ZXJmbG93
LmVtYWlsghJzdGFja292ZXJmbG93LmJsb2cwDgYDVR0PAQH / BAQDAgWgMB0GA1Ud
JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRw
Oi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzUuY3JsMDSgMqAw
hi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzUuY3Js
MEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMIGDBggrBgEFBQcBAQR3MHUw
JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBNBggrBgEFBQcw
AoZBaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkhpZ2hB
c3N1cmFuY2VTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH / BAIwADANBgkqhkiG9w0BAQsF
AAOCAQEARIdUz7n08ZtqWscAmTXegtB6yPrU0l5IQCXQRqnEVXPKyS + w8IVOcblT
T / W2Qlp5we2BTDbRDfVokXIOSxOTAT0XN3f3c + nbvKJ3XMBH236846AY6bpfqL0 /
05gcdt39d2iXTL + qnJW9P0yFKpkfGXBBTYQl4ACSeThSuSBXIVJ0v / TfR9 + ggXuP
pmXiIKkPOReKu2Tu8SO7 + 5KRqRJvYhP9mhL4Bl + YLrTQXzM1NwVAahRT1QJJNemy
yEY1kkZOCKt0xRu4CVWhJlpNdoRZenT9BrD8Fo22kt5MxAvCVrjT / g1BHDQd4S8p
PKC8kRwmMA8mdo8TiHJQMy0DBCDCDg ==
----- END CERTIFICATE -----
subject = / C = US / ST = NY / L = New York / O = Stack Exchange, Inc./CN=*.stackexchange.com
issuer = / C = US / O = DigiCert Inc / OU = www.digicert.com / CN = DigiCert SHA2 High Assurance Server CA

To copy the certificate to a file, use openssl again. Repeat the previous command and send its output to openssl x509 specify DER encoding and send it to a new file named stackexchange.com.der :

 : openssl s_client-connect api.stackexchange.com:443 </ dev / null
| openssl x509 -form DER-out stackexchange.com.der

If you have followed the steps correctly, you should be able to see that certificate in the same folder of your project.

 Saved certificate

Implement certificate stick

Before you enter the code, you must import the certificate you previously downloaded. Open PinMyCert.xcodeproj in Xcode, if you do not have it open.

Right click on the root PinMyCert folder in the project navigator. Click Add files to "PinMyCert" … and then select stackexchange.com.der and then click Add .

 Import certificate

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

  struct Certificates {
static la stackExchange =
Certificates.certificate (file name: "stackexchange.com")

private static func certificate (filename: string) -> SecCertificate {
leave the file path = Bundle.main.path (forResource: filename, ofType: "there")!
let data = try! Data (contentOf: URL (fileURLWithPath: filePath))
leave certificate = SecCertificateCreateWithData (null, data like CFData)!

Returns evidence
}
}

The above structure provides a user-friendly way to retrieve a certificate from the main package.

SecCertificateCreateWithData is responsible for creating a certificate object from a DER encoded file. NetworkClient.swift find NetworkClient and replace the entire line let session = Session.default with the following code:

  // 1
leave evaluators = [
  "api.stackexchange.com":
    PinnedCertificatesTrustEvaluator(certificates: [
      Certificates.stackExchange
    ])
]

let session: Session

// 2
private init () {
increase = increased (
serverTrustManager: ServerTrustManager (evaluators: evaluators)
)
}

Here is the breakdown of the code above:

  1. You create a dictionary called evaluators containing a single key value pair. The key is of the 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 the host in question. You use PinnedCertificatesTrustEvaluer to validate the server trust. The server trust is valid if the stapled certificate exactly matches the server certificate.
  2. You declare a private initializer that instances Session using ServerTrustManager . The latter is responsible for the control of the survey stated in the evaluator's dictionary.

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

  NetworkClient. request (Router.users)
.responseDecodable {(answer: DataResponse ) i
change response.result {
case .success (la value):
self.users = value.users
case. errors (leave errors):
self.presentError (withTitle: "Oops!", notification: error.localizedDescription)
}
}

Replace it with this new implementation:

  NetworkClient.request (Router.users)
.responseDecodable {(answer: DataResponse ) i
change response.result {
case .success (la value):
self.users = value.users
case. errors (leave errors):
la isServerTrustEvaluationError =
error.asAFError? .isServerTrustEvaluationError ?? false
leave message: String
if isServerTrustEvaluationError {
message = "Certificate Pinning Error"
} other {
message = error.localizedDescription
}
self.presentError (withTitle: "Oops!", message: message)
}
}

Although the success case remains the same, you have enriched the bug with an additional condition. First, try to discard error as a AFError . If the roll is successful, consider isServerTrustEvaluationError . If the value is true it means the certificate stick has failed.

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

But wait! If this is a guide that teaches you how to prevent human-in-center attacks, how can you be sure that you've done everything right when it's not attacked?

  Stop!

Only trust in traffic, please [19659018] To answer this question, go straight to the next section.

Test Certificate Pinning With Charles

To confirm that everything is going as expected, you must first download the latest version of Charles Proxy, which is version 4.2.8 at the time of this writing. Double-click the DMG file and drag the Charles icon to the Applications folder to install it.

Charles is a proxy server, a middleware that sits between your app and your computer's network connections. You can use Charles to configure the network settings to guide all traffic through it. This allows Charles to inspect all network events to and from your computer.

Proxy servers are in a great power position, which also means they have potential for abuse. Therefore, TLS is so important: Data encryption prevents proxy servers and other middleware from canceling sensitive information.

Charles generates his own self-signed certificate, which you can install on Mac and IOS devices for TLS encryption. Since this certificate is not issued by a trusted certificate issuer, you must tell that your devices explicitly trust it. Once installed and trusted, Charles will be able to decrypt SSL events.

However, in your case, Charles will not sniff your SSL messages. Charles' narrow man in the middle strategy won't work because your pinning strategy will hinder it.

Certificate stick in action

To see your enhanced security in action, start Charles. Charles starts recording network events as soon as it starts.

In Charles, first switch to the tab Sequence . Then type api.stackexchange.com into the filter box to make it easier to find the request you need and click on the cost icon to remove the current session.

 Charles User Interface

Click now on Proxy on the menu bar and select macOS Proxy to turn it on again (if it doesn't already show a tag ).

Then, click Proxy ▸ SSL Proxying Settings and add api.stackexchange.com to the list. You can leave the field Port empty. Select Enable SSL Proxying and click OK to confirm.

Note : Remember to deselect Enable SSL Proxying when you have finished testing. Otherwise you will not be able to run the app normally.

Then you need to install the Charles Proxy SSL certificate to allow proxying SSL requests in the simulator.

In Charles, click Help ▸ SSL Proxying ▸ Install Charles Root Certificate in iOS simulators . Then open the Settings app on the simulator. Point through General ▸ About ▸ Certificate Company Settings (it is at the bottom, so you may need to scroll). Press the switch to turn on Charles Proxy CA and press Continue in the resulting warning dialog.

Back in Xcode, build and run the project. You should see a warning as follows:

 Final screen

On the Charles side you should see an error such as that represented below:

 Charles Failure

]Congratulations! You can now download the completed version of the project using Download Materials . You can download the completed version of the project. Download materials link at the top or bottom of this tutorial.

You've learned how to get SSL certificate stick using Alamofire 5. Your users can now rest assured that attackers can't steal sensitive information from your apps.

When you're done experimenting with your app and Charles, it's important to remove the Charles CA certificate from the simulator. With the simulator active, select Hardware ▸ Delete all content and settings … from the menu, and then click Delete .

To learn more about SSL certificate stick and security in general, check the OWASP Mobile Security Testing Guide. It is a comprehensive test guide that covers processes, techniques and tools used in mobile app security tests.

Meanwhile, if you have any questions or comments, please join the forum discussion below!


Source link