iOS https单向配置
免责声明:本文内容来自互联网,用途仅为个人总结参考,如有雷同你来打我啊?
又到了喜闻乐见的写博客时间了,今天的主角是喧嚣已久的https,知其然要知其所以然,所以先捋一下他到底是什么
1,什么是SSL/TLS?跟HTTP和HTTPS有什么关系?
2,以前的HTTP不是也能用吗?为什么要用SSL/TLS,闲得慌?!Apple是不是又在反人类?
3,如何适配?---弱弱地问下:加班要多久?
//------------------
答案:
1,HTTP+SSL/TLS+TCP = HTTPS (TLS 是 SSL 新的别称)
打个比方:如果原来的 HTTP 是塑料水管,容易被戳破;那么如今新设计的 HTTPS 就像是在原有的塑料水管之外,再包一层金属水管。一来,原有的塑料水管照样运行;二来,用金属加固了之后,不容易被戳破。
这里用两张图来介绍两者的区别:
- HTTP:当客户端发送请求,那么服务器会直接返回数据。
- HTTPS:当客户端第一次发送请求的时候,服务器会返回一个包含公钥的受保护空间(也成为证书),当我们发送请求的时候,公钥会将请求加密再发送给服务器,服务器接到请求之后,用自带的私钥进行解密,如果正确再返回数据。这就是 HTTPS 的安全性所在。
2,不使用SSL/TLS的HTTP通信,就是不加密的通信!
所有信息明文传播,带来了三大风险:
-
窃听风险(eavesdropping):第三方可以获知通信内容。
-
篡改风险(tampering):第三方可以修改通信内容。
-
冒充风险(pretending):第三方可以冒充他人身份参与通信。
SSL/TLS协议是为了解决这三大风险而设计的,希望达到:
-
所有信息都是加密传播,第三方无法窃听。
-
具有校验机制,一旦被篡改,通信双方会立刻发现。
-
配备身份证书,防止身份被冒充
3,因为每次通讯都用到公钥和密钥,所以证书是必不可少的,一般证书由后台分派给iOS和Android,后台的证书可以自签名(方法:https://www.oschina.net/question/2308078_230138),也可以去各大认证机构购买
(1),当后台派发证书给你的时候,到手的证书可能是.crt格式的,这个时候需要把.crt格式的证书转换成.cer(操作方法:进到证书路径,执行下面语句
// openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der
这样你就可以得到cer类型的证书了。双击,导入电脑。)
(2),直接把转换好的cer文件拖动到工程中
(3),infoplist加入以下:<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
(4),设置afnetWorking的manager的配置属性即可正常请求:
AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
mgr.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",
@"text/html",
@"image/jpeg",
@"image/png",
@"application/octet-stream",
@"text/json",
nil];
// 设置添加的代码
NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"你拉到工程的cer证书的名称" ofType:@"cer"];
NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
mgr.securityPolicy.pinnedCertificates = [[NSArray alloc] initWithObjects:cerData, nil];
// 客户端是否信任非法证书
mgr.securityPolicy.allowInvalidCertificates = YES;
// 是否在证书域字段中验证域名
[mgr.securityPolicy setValidatesDomainName:NO];
-----------------------附上不用afn的童鞋的福利,原生OC代码配置:
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler { // 判断是否是信任服务器证书 if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) { // 告诉服务器,客户端信任证书 // 创建凭据对象 NSURLCredential *credntial = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; // 通过completionHandler告诉服务器信任证书 completionHandler(NSURLSessionAuthChallengeUseCredential,credntial); } NSLog(@"protectionSpace = %@",challenge.protectionSpace); }