由于苹果是17年的1月1日期审核要求强制开启ATS,所以各个应用的程序员都已经开始了https的适配。下面介绍一下我司的适配。
原理:
HTTPS连接建立过程大致是,当客户端和服务端连接的时候,服务端返回一个证书,客户端里存有受信任的证书机构根证书,用这些根证书对服务端返回的证书进行验证,经验证如果证书是可信任的,就生成一个pre-master secret,用这个证书的公钥加密后发送给服务端,服务端用私钥解密后得到pre-master secret,再根据某种算法生成master secret,客户端也同样根据这种算法从pre-master secret生成master secret,随后双方的通信都用这个master secret对传输数据进行加密解密。
开发:
因为我们的应用是使用猿题库的网络请求,而猿题库是在AFNetworking的基础上封装的,https的验证主要就是AFSecurityPolicy模块。
/**
验证方式
*/
@property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
/**
客户端的证书文件
*/
@property (nonatomic, strong, nullable) NSArray *pinnedCertificates;
/**
是否允许客户端验证通过一个无效的服务端证书
*/
@property (nonatomic, assign) BOOL allowInvalidCertificates;
/**
是否验证域名有效性
*/
@property (nonatomic, assign) BOOL validatesDomainName;
/**
生成一个默认的对象,会加载本地的bundle里寻找到的cer文件
*/
+ (instancetype)defaultPolicy;
/**
该域名是否通过证书验证
*/
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
forDomain:(nullable NSString *)domain;
如果你跟我一样使用的猿题库的框架,你只需要这样做.
// 配置HTTPS
YTKNetworkConfig *config = [YTKNetworkConfig sharedInstance];
config.baseUrl = @"";
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"" ofType:@""];
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
config.securityPolicy.allowInvalidCertificates = YES;
config.securityPolicy.validatesDomainName = NO;
config.securityPolicy.pinnedCertificates = @[certData];
这样就基本上结束了。
如果这时候用的有第三方的分享或者统计的sdk的话,更换一下sdk就好了;不能添加https的需要在plist里添加说明,
<key>sina.com.cn</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
如果服务器有用到cdn的或者oss对象存储的,在阿里云配一下证书就好了,需要上传私钥(这个有点儿担心),他默认的配置是支持http和https的,所以并不会影响老用户。改为https下载的话,我们可以使用证书验证,但是我为了方便下载,没有做这一步。
在NSURLConnection的回调里,只需要这样。
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
//默认验证通过
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
苹果这么做,也是为了用户的数据安全和隐私,虽然让很多厂商和开发者不爽,但是从长远看的话还是大势所趋,所以大家就辛苦一下赶紧适配吧。
补充:其实客户端适配Https没有必须强制要证书的,直接换一下URL就可以了。