完整的https请求的过程:
首先,浏览器请求一个url,找到服务器,向服务器发起一个请求。服务器将自己的证书(包含服务器公钥S_PuKey)、对称加密算法种类及其他相关信息返回客户端。
浏览器检查CA证书是不是由可以信赖的CA机构颁发的,确认证书有效和此证书是此网站的。如果不是,给客户端发一个警告,询问是否继续访问。
如果是,客户端使用公钥加密了一个随机对称密钥,包括加密的URL一起发送到服务器
服务器用自己的私匙解密了你发送的钥匙。然后用这把对称加密的钥匙给你请求的URL链接解密。
服务器用你发的对称钥匙给你请求的网页加密。你也有相同的钥匙就可以解密发回来的网页了。
说起来复杂,简单总结起来就是:
使用非对称加密传输一个对称密钥K,让服务器和客户端都得知。然后两边都使用这个对称密钥K来加密解密收发数据。因为传输密钥K是用非对称加密方式,很难破解比较安全。而具体传输数据则是用对称加密方式,加快传输速度。
1. NSURLSession实现
#import "ViewController.h"
@interface ViewController () <NSURLSessionTaskDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.apple.com/"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}];
[task resume];
}
#pragma mark - <NSURLSessionTaskDelegate>
/**
* challenge : 挑战、质询
* completionHandler : 通过调用这个block,来告诉URLSession要不要接收这个证书
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
{
// 如果不是服务器信任类型的证书,直接返回
if (![challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) return;
// void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)
// NSURLSessionAuthChallengeDisposition : 如何处理这个安全证书
// NSURLCredential :安全证书
// 根据服务器的信任信息创建证书对象
// NSURLCredential *crdential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
// 利用这个block说明使用这个证书
// if (completionHandler) {
// completionHandler(NSURLSessionAuthChallengeUseCredential, crdential);
// }
!completionHandler ? : completionHandler(NSURLSessionAuthChallengeUseCredential, challenge.proposedCredential);
}
@end
2.AFNetworking实现
直接换一下URL就可以。
// 使用baidu的HTTPS链接
NSString *urlString = @"https://www.baidu.com";
NSURL *url = [NSURL URLWithString:urlString];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer]
[manager GET:url.absoluteString parameters:nil progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"results: %@", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"results: %@", error);
}];