AFNetworking for HTTPS certification

AFNetworking for HTTPS certification
Write at the beginning:
  • This paper was prepared to write AFNetworking in the end what has been done? (three) in, but because I want to end this series in the third, due to the limited space, and this is a content of strong independence, so alone carry out, in the form of A.
  • From the point of view of source code, this paper analyzes the authentication process of AFNetworking to https. Designed to let readers understand that we are going to do HTTPS requests: what should we do if we use AF?. What do you need to do with native NSUrlSession directly if you don’t use it?. What problems should we pay attention to when we use the self signed certificate HTTPS?.
  • Reading alone does not affect reading. If you need more information about AF, you can focus on the title series: what exactly did
    AFNetworking do? What exactly did
    AFNetworking do? (two)
Then the text begins:

In simple understanding, https:https adds a certificate authentication process to the HTTP request. After authentication, data transmission is encrypted.
more on the concept of HTTPS, I will not go into details, there are a lot of articles online, small partners can consult on their own. Here’s a rough idea of HTTPS’s authentication process, as shown in figure below:

AFNetworking for HTTPS certification
HTTPS one-way authentication process.Jpg

1., the client launched the HTTPS request
, which is nothing to say, is that users enter a HTTPS URL in the browser, and then connect to the 443 port of server.
2. server configuration,
server using HTTPS protocol must have a set of digital certificates, you can make your own, you can also apply to the organization. The difference is that a certificate issued by yourself requires client authentication to continue, and a certificate that uses a trusted company does not prompt the page. The certificate is actually a pair of public keys and private keys. If you don’t understand the public key and private key, can be imagined as a key and a lock, but only one person you have the key, you can lock on to others, others can use the lock to lock up the important things, then to you, because you are the only one who has the keys so, only you can see by the lock up.
3. transmits certificate
. This certificate is actually a public key, but contains a lot of information, such as certificate authority, expiration date, and so on.
4 client certificate
analysis of this part of the work is a TLS/SSL client to complete the first certified public key is valid, such as authority, expiration time and so on, if abnormal, it will pop up a warning prompt box, certificate problems. If the certificate has no problem, a random value is generated. The random value is then encrypted with a certificate. As it says, lock the random values with a lock, so that unless you have the key, you can’t see the contents locked.
5 transmits the encrypted transmission of information in this part of
is encrypted with a random value certificate, the purpose is to let the server to get the random value, after the communication of client and server can encrypt and decrypt the value through the random. The
6. service segment decrypts the information, and the
server decrypts the random value (the private key) passed by the client after decrypting it with the private key, and then encrypts the content symmetrically through the value. The so-called symmetric encryption is the private key information and by some algorithm mixed together, so unless you know the private key, otherwise unable to access the content, and just the client and the server knows the private key, so long as the private key encryption algorithm is tough, complicated enough, enough data security.
7. transmits encrypted information,
, which is encrypted with the private key of the service segment and can be restored on the client side. The
8. client decrypts the information, and the
client decrypts the message from the service section with the previously generated private key, thus obtaining the decrypted content. The whole process, even if the third listening to the data, but also helpless.

This is the whole HTTPS validation process. Summarize briefly:

  • That is, the user initiates the request and returns a certificate after the server responds. The certificate contains some basic information and public key.
  • After the user gets the certificate, to verify that the certificate is legal, illegal, then request termination.
  • Legally, a random number is generated as the key of the symmetric encryption, and the random number is encrypted with the public key returned by the server. Then return to the server.
  • The server obtains the encrypted random number, uses the private key to decrypt, and then uses the decrypted random number (symmetric key) to encrypt the data which needs to be returned. After the encryption is completed, the data is transmitted to the user.
  • Finally, the user gets the encrypted data and uses the initial random number (symmetric key) to decrypt the data. The whole process is completed.

Of course, this is only a one-way authentication, HTTPS will also have two-way authentication, relative to one-way authentication is also very simple. Just more than the server authentication client this step. Interested can see this: Https one-way authentication and two-way authentication.

After understanding the HTTPS authentication process, let’s talk about the AFSecurityPolicy class, and AF uses this class to meet our various HTTPS certification requirements.

Before that, let’s take a look at AF’s proxy for HTTPS authentication:

- (void) URLSession: (NSURLSession * session) didReceiveChallenge: (NSURLAuthenticationChallenge * challenge) (completionHandler: (void ^ (NSURLSessionAuthChallengeDisposition) disposition, NSURLCredential *credential)) {/ / completionHandler / * NSURLSessionAuthChallengePerformDefaultHandling as the default type challenge: the default approach: NSURLSessionAuthChallengeUseCredential using the specified certificate: NSURLSessionAuthChallengeCancelAuthenticationChallenge / NSURLSessionAuthChallengeDisposition disposition to cancel the challenge = NSURLSessionAuthChallengePerformDefaultHandling; __block = NSURLCredential *credential nil; / / sessionDidReceiveAuthenticationChallenge is a custom method to how to deal with the server If authentication challenge end (self.sessionDidReceiveAuthenticationChallenge) {disposition = self.sessionDidReceiveAuthenticationChallenge (session, challenge, & credential) {else}; / / here server requires authentication challenge method for receiving client is NSURLAuthenticationMethodServerTrust / / that is returned to the client server to provide a protective space according to the authentication challenge trust (challenge.protectionSpace.serverTrust) generates challenge certificate. This certificate / / and you'll need to use the credentialForTrust: to create a NSURLCredential object if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {/ / security strategy based on client to decide whether or not to trust the server, don't trust it, it is not necessary to respond to the challenge of if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust]) {/ / create challenge Certificate (Note: the challenge for UseCredential and PerformDefaultHandling need a new challenge certificate) credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; / / the way to identify challenges If (credential) {/ / certificate of challenges in the design of policy none, is here, disposition = NSURLSessionAuthChallengeUseCredential;} else {disposition = NSURLSessionAuthChallengePerformDefaultHandling;}} else {/ / cancel the challenge of disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;}} else {/ / default disposition challenge mode = NSURLSessionAuthChallengePerformDefaultHandling;}} / / complete the challenge if (completionHandler) {completionHandler (disposition credential);}}

More details of this method, you can look at the notes, or consult the relevant articles before the landlord, have talked about this agent method. Here, let’s say something about what this method does:
1) first specifies that HTTPS is the default authentication method.
2) to determine there is no custom Block:sessionDidReceiveAuthenticationChallenge, yes, we use Block to generate a custom, authentication, and assignment to credential, we need to accept the certification certificate. Then call completionHandler directly to perform the system authentication based on these two parameters. As for the system certification, in the end what to do, you can read the article, finally, here for the time being.
3) if there is no custom Block, we determine if the server requires authentication method is NSURLAuthenticationMethodServerTrust, you only need to verify the server certificate is safe (i.e., one-way authentication, HTTPS AF this is the default processing methods, other methods of authentication, only by our custom Block Implementation)
4) and then we carried out a method of AFSecurityPolicy, made a AF inside a HTTPS certification:

[self.securityPolicy, evaluateServerTrust:challenge.protectionSpace.serverTrust,])

The default processing for AF is that if the line returns NO and indicates that the AF internal authentication fails, then the HTTPS authentication is canceled, or the request is canceled. When YES is returned, the if block is entered, and an authentication certificate is generated with a serverTrust returned by the server. (Note: the serverTrust server is coming, which contains the server certificate information is used to our local client to verify this certificate is legitimate use, later more detailed to tell this parameter) then if there is a certificate, certificate authentication, or use the default authentication. Finally, call completionHandler to pass the authentication method and the certificate to be authenticated, and do the system root certificate validation.

  • To sum up, the role of securityPolicy here is that before you can validate yourself at the bottom of the system, AF can first validate the server’s certificate. If you can’t pass it, go through the system validation and cancel the HTTPS network request. Otherwise, proceed to the validation of the system root certificate.
Next, we’ll see if HTTPS is certified within AFSecurityPolicy:

As follows, we can create a securityPolicy:

AFSecurityPolicy *policy = [AFSecurityPolicy defaultPolicy];

Internal creation:

+ (instancetype) defaultPolicy {AFSecurityPolicy = [[self alloc] init]; securityPolicy.SSLPinningMode = AFSSLPinningModeNone; return securityPolicy;} *securityPolicy

The default specifies a SSLPinningMode schema of AFSSLPinningModeNone.
for AFSecurityPolicy, there are 4 important attributes:

//https @property (readonly, nonatomic authentication mode, assign AFSSLPinningMode SSLPinningMode); / / can go to the server certificate verification certificate, @property (nonatomic, strong, nullable) NSSet < NSData *> *pinnedCertificates; / / whether to support the illegal Certificate (e.g. self signed certificate) @property (nonatomic, assign) BOOL allowInvalidCertificates; / / whether to verify whether the domain name certificate (nonatomic, @property, assign) BOOL validatesDomainName;

I added them to the notes, and the first is AFSSLPinningMode, which provides 3 authentication methods:

Typedef NS_ENUM (NSUInteger, AFSSLPinningMode) {/ / AFSSLPinningModeNone / / not only verify the public key verification, AFSSLPinningModePublicKey, AFSSLPinningModeCertificate} / / verification certificate;

We then go back to the code for the proxy HTTPS authentication:

[self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust]
  • We pass in two arguments, and one is the serverTrust of the SecTrustRef type. What is this? We see the apple documentation as follows: CFType used for performing X.509 trust certificate evaluations. probably means to execute X. 509 certificate trust evaluation,
    more simple, is actually a container installed server need to verify the certificate of the basic information, public key and so on, moreover, it can also put some evaluation strategy, and the client’s anchor certificate, the client certificate and server certificate can be used to verify the matching.
  • In addition, the server domain name was passed.

We came to this method and the code is as follows:

/ / authentication server is trustworthy - (BOOL) evaluateServerTrust: (SecTrustRef) serverTrust forDomain: (NSString * domain) {/ / / / judgment contradictory condition judgment domain, and allow the self certificate, need to verify the domain name, because of the need to verify / / domain name, so must be the latter two types: AFSSLPinningModeNone or added to the project certificate 0. If (domain & & self.allowInvalidCertificates; & & self.validatesDomainName & & (self.SSLPinningMode = = AFSSLPinningModeNone ||; [self.pinnedCertificates count] = = 0)) {/ / / / documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html According to the docs, you should only trust your provided certs for evaluation. certificates are added to / / Pinned the trust. Without pinned certificates, is nothing to / / there evaluate against. From Apple Docs: / / / / / / "Do not implicitly trust self-signed certificates as anchors (kSecTrustOptionImplicitAnchors) / /. Instead, add your own (self-signed) CA certificate to the list of trusted anchors. NSLog (order to validate a @ In domain name for self signed certificates, you MUST use pinning. "); / / untrusted, return return NO;} / / used to hold the verification strategy for NSMutableArray *policies = [NSMutableArray array]; / / to verify the domain name if (self.validatesDomainName) {/ / if you need to verify the domain, then use the SecPolicyCreateSSL function to create a validation strategy in which the first parameter is true that validated the SSL certificate chain, second parameters to the domain, the domain is used to determine the leaf node the certificate chain said whether the incoming domain here and consistent verification strategy [policies / / add addObject: (__bridge _transfer ID (SecPolicyCreateSSL) true (__bridge, CFStringRef) domain)];} else {/ / if you do not need to verify the domain, use the addObject: BasicX509 verification strategy [policies default (__bridge_transfer ID) (SecPolicyCreateBasicX509)];} / / serverTrust:X. 509 server certificate trust. / / set validation strategy for serverTrust, which tells the client how to verify serverTrust SecTrustSetPolicies (serverTrust (__bridge, CFArrayRef) policies); / / validation strategy, to verify the. If AFSSLPinningModeNone is self signed, directly returned, trusted, otherwise it is not self signed, go to the root certificate of the system to see if there is a matching certificate. If (self.SSLPinningMode = = AFSSLPinningModeNone) {/ / if self signature, return directly to YES, are not allowed to judge the second conditions, to determine whether the serverTrust return self.allowInvalidCertificates AFServerTrustIsValid || (serverTrust);} / / if authentication is not AFServerTrustIsValid, but allowInvalidCertificates does not allow self signed, else if returns NO (serverTrust) & AFServerTrustIsValid (! & return NO; self.allowInvalidCertificates) {!}; / / judge SSLPinningMode switch (self.SSLPinningMode) {/ / theory, the above has been solved for self.SSLPinningMode) AFSSLPinningModeNone) etc., so to meet again, NO case AFSSLPinningModeNone: default: return directly Return NO case AFSSLPinningModeCertificate:; / / verification certificate type {NSMutableArray *pinnedCertificates = [NSMutableArray array]; / / the certificate of data, with API system into SecCertificateRef data types, SecCertificateCreateWithData function to do some processing on the original pinnedCertificates, ensure that the return certificate is DER encoding X.509 (NSData *certificateData in self.pinnedCertificates certificate for [pinnedCertificates addObject: (__bridge_transfer) {ID (SecCertificateCreateWithData) NULL (__bridge, CFDataRef) certificateData)]}; / / set the pinnedCertificates Anchor Certificate needs to participate in the verification (anchor certificate by SecTrustSetAnchorCertifi After cates set the check in the anchor certificate, if digital certificate verification certificate is the anchor node, namely the validation of digital certificate is issued by the corresponding CA or CA anchor certificate, or the certificate itself, then trust the certificate), specifically is to call SecTrustEvaluate to verify. //serverTrust is the authentication from the server, and there is a certificate that needs to be validated. SecTrustSetAnchorCertificates (serverTrust (__bridge, CFArrayRef) pinnedCertificates); / / self signed before is verified by the deal. In this step, after our own set of certificate added, can verify the success. / / before going to call serverTrust to verify that the certificate is valid, there may be: after this method after filtration, inside the serverTrust pinnedCertificates was screened only one certificate trust if (! AFServerTrustIsValid (serverTrust)) {return NO;} / / obtain the chain after being validated, which *should* contain the pinned Certificate in the last position (if it's the Root CA) / / note that this method and the anchor certificate before we never mind, is to be verified from what we need to get the server certificate, certificate chain. / / server certificate chain, pay attention here to return the certificate chain order is from the leaf node to the root node of NSArray *serverCertificates = AFCertificateTrustChainForServerTrust (serverTrust); //reverseObjectEnumerator (NSData *trustChainCertificate in inverse for [serverCertificates reverseObjectEnumerator]) {/ / if we have a certificate, and certificate certificates in the chain, and returns YES if ([self.pinnedCertificates containsObject:trustChainCertificate]) {return YES}}; / / no, return NO;} / / AFSSLPinningModePublicKey mode is also using the public key authentication certificate binding (SSL Pinning). Type authentication, the client should have a copy of the server's certificate, but only verify the public key in the certificate, and not verify the validity of the certificate. As long as the public key is correct, the communication can be guaranteed not to be bugged because the middleman has no private key and cannot unlock data encrypted through public keys. Case AFSSLPinningModePublicKey: NSUInteger {trustedPublicKeyCount = 0; / / remove all available certificate server from the serverTrust in the end came, and then get the corresponding public key NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust (serverTrust); / / for (ID trustChainPublicKey traversal server public key in publicKeys) {/ / for (ID pinnedPublicKey traversal local public key in self.pinnedPublicKeys) {/ / if the same trustedPublicKeyCount+1 if (AFSecKeyIsEqualToKey ((__bridge SecKeyRef) trustChainPublicKey (__bridge, SecKeyRef) pinnedPublicKey)) {trustedPublicKeyCount = 1; }} return, trustedPublicKeyCount, > 0;}, return, NO;}

Code a lot of comments, this one is really dry, you can refer to the source code to see together, deepen understanding.

  • This method is the most central method of AFSecurityPolicy, and the other is to match this method. This method completes the trust evaluation of the server’s certificate. Let’s sum up what this method does (see the note in detail): according to the model, if it is AFSSLPinningModeNone, then it must return YES, whether it is a self signed or a public trust certificate. If it is AFSSLPinningModeCertificate, from the serverTrust to obtain the certificate chain, and then we started to initialize the certificate set self.pinnedCertificates to match, if there is a matching success, otherwise it returns YES, NO.
    see, maybe there’s a little buddy to ask, what is the certificate chain? The following paragraph is extracted from the Encyclopedia: the certificate chain consists of two links – the trust anchor (CA certificate) link and signed certificate link. The self signed certificate has only one link length – the trust anchor section is the signed certificate itself. In short, the certificate chain is the root certificate and the certificate that is distributed according to the root certificate signature. If AFSSLPinningModePublicKey public key authentication is the same as the second step, or from serverTrust, get the certificate chain, the public key of each certificate, and put it in the array. Pair with our self.pinnedPublicKeys, and if one is the same, return YES, otherwise NO. As for the self.pinnedPublicKeys, initialization of the following: / / set up certificate – (void) setPinnedCertificates: array (NSSet * pinnedCertificates) {_pinnedCertificates = pinnedCertificates; / / get the corresponding public key set if (self.pinnedCertificates) {/ / create the public collection of NSMutableSet *mutablePinnedPublicKeys = [NSMutableSet setWithCapacity:[self.pinnedCertificates count]]; / / get the public key from the certificate. For (NSData *certificate in self.pinnedCertificates) {ID publicKey = AFPublicKeyForCertificate (certificate); if (! PublicKey) {continue}}; [mutablePinnedPublicKeys addObject:publicKey]; self.pinnedPublicKeys [NSSet setWithSet: = mutablePinnedPublicKeys];} else {self.pinnedPublicKeys = nil;}} AF carbon set certificate set method, and at the same time, each public key certificate on the self.pinnedPublicKeys in.

This method is related to a series of functions, and I’m here to list them in the order of calls (some of the system functions are not listed here and will be described collectively in the following sections):

Function 1: AFServerTrustIsValid
To determine whether the serverTrust static BOOL / AFServerTrustIsValid (SecTrustRef serverTrust) {/ / default isValid invalid BOOL = NO; / / to verify the results, result //__Require_noErr_Quiet used to determine the enumeration of SecTrustResultType; the former is 0 or 0, if 0 said yes, jumped to the back of the expression location to perform, or said wrong to to perform. The //SecTrustEvaluate system evaluate the trustworthiness of the certificate, go to the root directory of the system, and then assign the result to result. The assessment results, return 0, otherwise an error return 0 //do while 0, only once, why should we write this... (__Require_noErr_Quiet. SecTrustEvaluate (serverTrust, & result, _out)); / / assessment not only two off this error, results can be set to isValid=, when result is 1 / / kSecTrustResultUnspecified (the sign serverTrust evaluation, this certificate has been secretly trust, but the user does not show the decision to trust the certificate). Result (kSecTrustResultProceed / / or when this flag indicates that successful evaluation, and the different is the assessment accepted by users), both one can think the success of isValid evaluation of serverTrust (result = = = = = kSecTrustResultProceed; result kSecTrustResultUnspecified ||) //out function block, if SecTrustEvaluate, return 0, assess isValid NO _out: error, return isValid;}
  • This method is used to verify the validity of the serverTrust, which is mainly referred to the system APISecTrustEvaluate to verify, it verified returns a SecTrustResultType enumeration type result, then we according to this result to determine whether the certificate is valid.
  • One of the more interesting is that it calls the macro function __Require_noErr_Quiet a system definition, function definition is as follows: #ifndef __Require_noErr_Quiet #define __Require_noErr_Quiet (errorCode, exceptionLabel) {/ / do / if (__builtin_expect (0! = (errorCode), 0)) {/ / goto / while / exceptionLabel;}} (0 this #endif) The main function of a function is to judge whether the errorCode is 0, not 0, and the program jumps to the exceptionLabel position with goto. This exceptionLabel is a code location identifier, similar to the _out above. The interesting thing about
    is that it uses a do, while (0) loop, and the loop condition is 0, that is, only one cycle is over. To do so, you remain perplexed despite much thought… It seems like native API is the frost God too profound to be understood… Remind, to do so is to fit the early API??!
Function two or three (two functions are similar, so put together): get the serverTrust certificate chain certificate and get the serverTrust certificate chain public key
Obtain the certificate chain static NSArray / * AFCertificateTrustChainForServerTrust (SecTrustRef serverTrust) {/ / use the SecTrustGetCertificateCount function to get to the serverTrust need to be evaluated in the certificate chain certificate number, and save it to a certificateCount CFIndex certificateCount = SecTrustGetCertificateCount (serverTrust); / / create an array of NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity: (NSUInteger) / certificateCount]; use the SecTrustGetCertificateAtIndex function to get to every a certificate in the chain, and added to the trustChain trustChain for (CFIndex, finally returning to I = 0; I < certificateCount; i++) {SecCertificateRef certificate = SecTrustGetCertificateAtIndex (serverTrust, I); [trustChain addObject: (__bridge_transfer, NSData *) SecCertificateCopyData (certificate)]} return, [NSArray, arrayWithArray:trustChain];}
/ / all available from the serverTrust server certificate out in the end came, and then get the corresponding public key static NSArray * AFPublicKeyTrustChainForServerTrust (SecTrustRef serverTrust) {/ / the next piece of code and AFCertificateTrustChainForServerTrust function are basically the same, in order to get all the certificates in the serverTrust certificate chain, and in order traversal, remove public key. Policy = SecPolicyCreateBasicX509 SecPolicyRef / / security policy (CFIndex); certificateCount = SecTrustGetCertificateCount; *trustChain = NSMutableArray (serverTrust) [NSMutableArray arrayWithCapacity: certificateCount] (NSUInteger); / / serverTrust traversal certificate chain. For (CFIndex I = 0; I < certificateCount; i++) {/ / SecCertificateRef certificate for a certificate from the certificate chain = SecTrustGetCertificateAtIndex (serverTrust, I); / / array SecCertificateRef someCertificates[] = {certificate}; //CF = CFArrayCreate (NULL certificates CFArrayRef array (const, someCertificates, void * *) 1, NULL); SecTrustRef trust; / / according to given certificates and policy to create a trust object / / not successful jump to _out. __Require_noErr_Quiet (SecTrustCreateWithCertificates (certificates, policy, & trust), _out); SecTrustResultType result; / / use SecTrustEvaluate to evaluate the above construction failed to evaluate trust / / jump to _out __Require_noErr_Quiet (SecTrustEvaluate (trust, & result, _out)); / / if the trust meets the X.509 certificate format, then use SecTrustCopyPublicKey to get to trust the public key, the public key is added to the trustChain [trustChain addObject: (__bridge_transfer ID) SecTrustCopyPublicKey (trust)] _out: / / if; the release of resources (trust) {CFRelease} (trust); if (certificates) CFRelease (certificates) {}} (CFRelease; continue; Policy); / / return [NSArray arrayWithArray:trustChain] a group public key corresponding to the return;}

The two methods function similarly, calling some system API and using the For loop to obtain each certificate or public key on the certificate chain. Specific content, see the source code, very good understanding. The only thing to note is that the obtained certificate sort is from the leaf node of the certificate chain to the root node.

Function four: determine whether the public key is the same
The two is the same as the public key / judge static BOOL AFSecKeyIsEqualToKey (SecKeyRef key1, SecKeyRef key2) {#if TARGET_OS_IOS TARGET_OS_WATCH TARGET_OS_TV //iOS || || judgment two address return (__bridge ID key1) [isEqual: (__bridge ID key2]); #else return [AFSecKeyGetData (key1) isEqual:AFSecKeyGetData (key2)]; #endif}

The method matches the running environment and makes the match judgment.

Next, list the system native functions that have been invoked during the validation process:
//1. creates a SSL validation strategy, two parameters, the first parameter of true said the whole verification certificate chain / second parameter domain, domain is used to judge whether the whole leaf node certificate chain said the introduction of domain and SecPolicyCreateSSL (< #Boolean server#> the < #CFStringRef; _Nullable, hostname#> SecPolicyCreateBasicX509) (BasicX509); //2. verification by default, does not verify the domain name. SecPolicyCreateBasicX509 (//3.); set the verification strategy for serverTrust, which tells the client how to verify serverTrust SecTrustSetPolicies (< #SecTrustRef _Nonnull trust#> <, #CFTypeRef; _Nonnull policies#> //4.) serverTrust verification and the verification results are returned to the second parameters of result SecTrustEvaluate (< #SecTrustRef; _Nonnull trust#> <, #SecTrustResultType; _Nullable * result#>) //5. errorCode of the former is 0 to 0 jump to exceptionLabel department execute code __Require_noErr (< #errorCode#> < #exceptionLabel#> //6., data) according to the certificate, to create the SecCertificateRef data type. SecCertificateCreateWithData (< #CFAllocatorRef _Nullable allocator#> <, #CFDataRef; _Nonnull data#> //7. serverTrust) to set the anchor certificate, if again to verify the serverTrust, whether from the anchor certificate to find matching. SecTrustSetAnchorCertificates (serverTrust (__bridge, CFArrayRef) pinnedCertificates //8.); get the certificate in the chain certificate number CFIndex certificateCount = SecTrustGetCertificateCount (serverTrust); //9. to obtain the certificate chain corresponding subscript certificate. SecTrustGetCertificateAtIndex (serverTrust, I) //10. gets the public key from the certificate. SecTrustCopyPublicKey (trust)

Its functions such as notes, we can compare the source code to understand ~!

AFNetworking for HTTPS certification
partition diagram.Png

may see this, and some small partners confused, talked so much, then if you do HTTPS request, we really need to do it ourselves, in the end what is it? Here to answer, divided into the following two cases:

  1. If you’re using a certificate issued by a paying public trust, the standard HTTPS, then you don’t have to do anything, whether you use AF or NSUrlSession, and the proxy method is not implemented. Your network request will be completed properly.
  2. If you are using a self signed certificate: first you need to set the plist file to return an unsafe request (the ATS that closes the domain name). Secondly, if it is NSUrlSesion, then the need to implement the following methods: in the agency – (void) URLSession: (NSURLSession * session) didReceiveChallenge: (NSURLAuthenticationChallenge * challenge) (completionHandler: (void ^ (NSURLSessionAuthChallengeDisposition) disposition, NSURLCredential *credential completionHandler __block NSURLCredential)) {*credential = nil; credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; / / if (determined to challenge the way credential) {/ / certificate of challenge here disposition = NSURLSessionAuthChallengeUseCredential;} / / complete the challenge if (completionHandler) {completionHandler (disposition, credential);}} is actually the relative to AF Simplified version of self signed certificate. If
    is AF, you need to set the policy:// to allow a self signed certificate must be policy.allowInvalidCertificates = YES; / / CN / / field to verify whether the domain name is not required, but if you write YES, you must import the certificate. Policy.validatesDomainName = NO; of course, can also according to the needs, you can go to verify the certificate or the public key, the premise is that you have a self signed certificate server, or CA root certificate is self signed into the project:
    AFNetworking for HTTPS certification
    and set the following certificate certificate: NSString *certFilePath = [[NSBundle mainBundle] pathForResource:@ “AFUse_server.cer” ofType:nil]; NSData *certData = [NSData dataWithContentsOfFile:certFilePath]; NSSet *certSet = [NSSet setWithObjects: certData, certData, nil]; policy.pinnedCertificates = certSet; different AFSSLPinningMode so you can use AF to verify.
Finally, what does AF do to HTTPS in the end?:
  • AF allows you to validate yourself before the system verifies the certificate. Then, if your verification is incorrect, the network request is canceled directly. Otherwise, system validation is continued by validation.
  • At this point, incidentally, system validation process: system validation, the first is to find the root certificate system, to see if there is a matching server certificate, if the match is successful, secure data return https. If not, determine if the ATS is closed and, if closed, returns the data for the HTTPS insecure connection. If ATS is turned on, the request is rejected and the request fails.

In a word: AF authentication is not necessary, but it is necessary for users with special verification requirements.

Written at the end:

  • After reading, some buddy may still be more confusing, advice or unclear buddy, can generate a self signed certificate or Baidu address made the request, and then set the AFSecurityPolicy parameters, break point, step by step to see how the AF is going to call for a certificate. I believe this will deepen your understanding.
  • Finally, the issue of self signed certificates, such as January 1, 2017, has not been much longer than a month. It is no longer possible to pass the audit unless there are special reasons. See this article in detail: iOS 10 adaptation, ATS (APP support, HTTPS through App, Store audit).
  • Finally, I hope you can point a praise, concern about ~ (see the landlord of praise and concern will be very happy…) what are the different opinions or suggestions or comments can be Jane I ~ if someone reproduced, trouble to indicate the source, thank you.
Apple’s official website of the latest news: originally scheduled for 2017.1.1 mandatory HTTPS was postponed, the specific delay until when the uncertainty, and so on and so on the official notification:
AFNetworking for HTTPS certification
Apple official news.Png
Follow-up article:

What does
AFNetworking do in AFNetworking extensions and caching implementations of UIKit? (end)