面试题答案
一键面试关键原理
- 证书验证机制:自签名证书没有经过受信任的证书颁发机构(CA)签名,所以默认情况下,iOS系统会拒绝该证书。需要在客户端实现自定义的证书验证逻辑,绕过系统默认的严格验证,同时保证通信安全。
- SSL/TLS握手过程:客户端和服务器在建立连接时,会进行SSL/TLS握手。在握手过程中,服务器会向客户端发送其证书,客户端需要验证该证书的有效性。
关键代码
- 配置AFNetworking(以AFNetworking为例,常用的网络框架)
- 首先导入AFNetworking头文件:
#import <AFNetworking/AFNetworking.h>
- 创建一个`AFHTTPSessionManager`实例,并配置其安全策略:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 自定义安全策略
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
// 允许无效证书(自签名证书属于无效证书)
securityPolicy.allowInvalidCertificates = YES;
// 是否验证域名,一般设置为YES
securityPolicy.validatesDomainName = YES;
manager.securityPolicy = securityPolicy;
- 验证服务器证书(在AFNetworking中进一步处理)
- 实现
AFURLSessionManagerDelegate
协议中的URLSession:didReceiveChallenge:completionHandler:
方法:
- 实现
@interface ViewController () <AFURLSessionManagerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 配置AFHTTPSessionManager代码省略
manager.session.configuration.URLCache = nil;
manager.sessionDelegate = self;
}
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
} else {
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}
}
@end
上述代码中,AFSSLPinningModeCertificate
表示采用证书固定模式,allowInvalidCertificates
设置为YES
允许无效证书,validatesDomainName
设置为YES
确保域名验证。在URLSession:didReceiveChallenge:completionHandler:
方法中,对服务器信任进行处理,使用NSURLCredential
创建信任凭证,以完成证书验证过程。这样就可以在Objective - C中实现与使用自签名证书服务器的可靠SSL/TLS加密通信。