Camp David Education original articles, reproduced please indicate the source. Our dream is to do the best iOS development training!
iOS app network security HTTPS1. The basic principle of HTTPS/SSL
Secure Sockets Layer, SSL, is the most common standard for secure communication over the Internet. The WEB application uses HTTPS (SSL-based HTTP) and HTTPS uses digital certificates to ensure secure, encrypted communication between the server and the client. In an SSL connection, both the client and the server encrypt the data before sending the data, which is then decrypted by the receiver.
when the browser (client) needs to establish a connection to a secure site, a TCP connection (three handshake) is established before the SSL session handshake occurs:
- The
Browser sends a message requesting a secure session over the network (typically requesting a URL that begins with https instead of HTTP). The
-
Server responds by sending its certificate, including the public key. The
-
Browser verifies that the server's certificate is valid and verifies that the certificate was issued by a (and trusted) CA that has its certificate in the browser's database. It also verifies that the CA certificate has expired.
-
If the certificate is valid, the browser generates a = = one-time, unique = = Session key and encrypts the session key using the server's public key. The browser then sends the encrypted session key to the server so that both the server and the browser have a session key. The
-
Server can use its private key to decrypt the message and then resume the session key.
After the handshake, the client has verified the identity of the Web site, and only the client and the Web server have a copy of the session key. From now on, the client and server can use the session key to encrypt all communication between them. This ensures the security of the communication between the client and the server.
The above is generally the most common one-way authentication method, by the browser (client) to verify the legitimacy of the server, in fact, you can also do two-way authentication, servers can also verify the legitimacy of the browser (client), but generally used in banking, such as U shield. We now focus on the application of the universal one-way verification method.
2. iOS Mobile development HTTPS application Status
Most of the mobile Internet projects now use HTTP, HTTPS protocol as the data interface protocol in front and back. The majority of iOS developers in the project application of the third party Open source HTTP request Framework afnetworking to fast and efficient development, after all, fast fish eat slow fish era. Afnetworking request HTTP interface is simply not easy anymore. Just starting from iOS9.0 you need to set up Info.plist app Transport Security to open a non-HTTP resource load, because Apple defaults to only HTTPS sites with certificates signed by an authoritative certification authority, all for security. Safety. Safety. Then we focus on the use of the HTTPS protocol to the background interface general usage: HTTPS server configuration of the certificate divided into two categories, a class is issued by the authority signed certificate, so that the certificate is usually to pay to buy services, of course, there are a few institutions to provide free certificate signing services. The other is that the server is configured with a certificate generated by the developer's own signature.
3.AFN invoke HTTPS interface that uses authoritative authority to issue certificates
Now that the afnetworking framework has fixed the SSL man-in-the-middle attack vulnerability in the first half of the year and strongly requires developers to use public key bindings or certificate binding security policies, the correct use of the HTTPS site code for afnetworking requests for such certificates is simple as follows:
Afsecuritypolicy *policy = [Afsecuritypolicy Policywithpinningmode:afsslpinningmodepublickey]; Policy.validatesdomainname = YES; Afhttpsessionmanager *manager = [Afhttpsessionmanager manager]; Manager.securitypolicy = policy; Manager.requestSerializer.cachePolicy = Nsurlrequestreloadignoringlocalcachedata;
For this type of certificate of the site, info.plist do not need to set up, because it is already issued by the authority of the certificate, we only need to set the authentication binding method and verify the domain name to prevent the man-in-the-middle attack, after all, the application certificate is spent money (now also have free applications, such as Wosign), a little easier
4.AFN calls the HTTPS interface using our own signing certificate
For the use of our own signed certificate, the browser opens the Web site will also be blocked by default, unless the user manually put the site into the trust list, this manual join process is not to verify the legitimacy of the server, wayward that the server is trustworthy. Then manually join the trust list, which will lead to the verification process of the certificate does not occur at all, although the target server can successfully access the data we need, in fact, it is very likely that the data returned is not a true target server returned data, it may be the network transmission in the middle of the third party disguised data returned. It is possible that the transmitted data is stolen or even tampered with.
4.1 Incorrect procedure
The ability of the browser to manually join the self-signed site to the trust list is equivalent to the Afnetworking API in iOS development:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
site https://tv.diveinedu.com is the self-signed certificate of the configuration method configuration described in my previous blog.
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //allow certificates issued by non-authoritative organizations manager.securitypolicy.allowinvalidcertificates = yes; //also does not verify domain consistency manager.securitypolicy.validatesdomainname = no; //turn off cache to avoid interference test manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData; [manager get:@ "https://tv.diveinedu.com/channel/" parameters:nil progress:nil success:^ (nsurlsessiondatatask * _nonnull task, id _nullable Responseobject) { nslog (@ "%@", Responseobject); } failure:^ (nsurlsessiondatatask * _nullable task, nserror * _ Nonnull error) { nslog (@ "%@", error); }];
After the two-step setup, we can access our HTTPS site with a self-signed certificate in our iOS app. But this is not safe because he has access to server resources without using HTTPS/SSL proxies and using HTTPS/SSL proxies like Charles. Can be said to be a waste of Kung fu, can only prevent "gentleman" in the network with Wireshark and so on to TCP capture packet sniffing. Because after all, HTTPS encrypted the transmission of data. Then why do I say this is a waste of effort, because this method can not prevent the man-in-the-middle attack! For example, the user can set up an HTTPS SSL proxy (such as Charles), can see clear text data in the agent, so, since the use of HTTPS to prevent the man-in-the-middle attack, or not the HTTPS.
Let's take a look at how to use the data from the HTTPS transport captured by the Charles Agent capture Kit Tool:
650) this.width=650; "src=" http://io.diveinedu.com/images/charles_https_unsafe.jpg "/>
is to run the Charles Tool agent grab packet on Mac, the real machine and Mac computer with a local area network, and set the proxy for Mac machine IP and Charles's proxy port 8888, and then start the app to request the network after the captured data. Isn't it a surprise? HTTPS data is also captured in clear text. Obviously this is very insecure, so when we use self-signed certificates, how can we be on the app side (client) to strictly verify the legitimacy of the server?
4.2 The right procedure
We want to strictly verify the legality of the server in the app side, to prevent the intermediary in the middle of the network agent or firewall attack and certificate spoofing, then we need to package the server configuration of the certificate into the client program (the private key to leave the server do not distribute, very important), in the code to read the certificate/ The public key information and the server returns the matching validation. In iOS development, starting with Xcode7 and iOS9, Apple has enhanced the Internet security of the app, which is only accessible by default to Web sites that issue certificates with authoritative authority signatures (trusted HTTPS), and HTTPS sites for self-signed certificates are listed as exceptions. So we need to set exception Domains
"White list" instead of opening allow arbitrary Loads
All release, set the information as follows:
650) this.width=650; "src=" Http://io.diveinedu.com/images/xcode_info_plist_ats.png "/>
<key >NSAppTransportSecurity</key> <dict> <key>nsexceptiondomains</key> <dict > <key>tv.diveinedu.com</ key> <dict> <key> nsexceptionallowsinsecurehttploads</key> <true/> </dict> </dict> </dict>
This is not the same as the above method of cutting all open, but a separate for a domain name release settings. Of course, the above can also be used to release all the settings NSAllowsArbitraryLoads
for true
. But I recommend using a whitelist.
In addition, in order to strictly verify the prevention of the Middleman like Charles, the agent grab packets, the afnetworking code should be set as follows:
After the //server-side configuration of the certificate that contains the public key is distributed to the client, you need to convert the certificate file to der format. //openssl x509 -outform der -in tv.diveinedu.com.crt -out tv.diveinedu.com.der nsstring *certfilepath = [[nsbundle mainbundle] pathforresource:@ " Tv.diveinedu.com " oftype:@" der "]; nsdata *certdata = [nsdata datawithcontentsoffile:certfilepath]; nsset *certset = [nsset Setwithobject:certdata]; afsecuritypolicy *policy = [afsecuritypolicy policyWithPinningMode:AFSSLPinningModePublicKey withPinnedCertificates:certSet]; policy.allowinvalidcertificates = yes; afhttpsessionmanager * manager = [afhttpsessionmanager manager]; manager.securitypolicy = policy; //offClosed cache avoidance Interference test manager.requestSerializer.cachePolicy = nsurlrequestreloadignoringlocalcachedata; [manager get:@ "https://tv.diveinedu.com/ channel/" parameters:nil progress:nil success:^ (nsurlsessiondatatask * _nonnull Task, id _nullable responseobject) { NSLog (@ "%@", Responseobject); } failure:^ (nsurlsessiondatatask * _ Nullable task, nserror * _nonnull error) { nslog (@ "%@", error); }];
The above code can verify that the server identity can access the server's resources without using the proxy, but once the user gives the mobile network settings using the HTTPS/SSL Proxy service such as Charle, the server certificate validation fails and the SSL network connection disconnects. The boss no longer has to worry about the data interface is grabbed by the person or the agent to get out. Therefore, the effect of preventing man-in-the-middle attack is achieved.
When using the Charles SSL proxy, Xcode debug terminal error message graph:
650) this.width=650; "src=" Http://io.diveinedu.com/images/xcode_ios_https_charles_fails1.png "/>
Proxy Server Charles's error message graph:
650) this.width=650; "src=" Http://io.diveinedu.com/images/xcode_ios_https_charles_fails2.png "/>
Finally, for iOS9 and OSX 10.11 Development, please refer to the Apple official documentation for Xcode's Info.plist nsapptransportsecurity detailed setup method: Nsapptransportsecurity Reference
Camp David Academy (Advanced Development Video): http://v.diveinedu.com
The club of Great concentration (iOS interview required): Http://divein.club
HTTPS for iOS app network security