这里以向https://api.github.com发送请求为例。
把自定义的CA证书放入工程:
这里以HTTP代理工具Charles作为中间人来演示。关于该工具的使用方法, 本文暂不论述. 这里仅用它来展示自签名证书的请求效果.
https://api.github.com网址的证书实际上是正规CA
DigiCert
签发的, 这里把Charles的CA根证书导入系统并设为信任后, 把Charles设为该网址的SSL Proxy (相当于"中间人"), 这样通过代理访问服务器返回将是由Charles伪CA签发的证书.
本例假设 https://api.github.com的服务器证书是自签的.
全部代码如下:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//你请求的网络服务返回的是JSON数据
manager.responseSerializer = [AFJSONResponseSerializer serializer];
//自定义security policy, 先前确保你的自定义CA证书已放入工程Bundle
NSSet <NSData *> *cerSet = [AFSecurityPolicy certificatesInBundle:[NSBundle mainBundle]];
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:cerSet];
policy.allowInvalidCertificates = YES;
manager.securityPolicy = policy;
//实际应用中把https://api.github.com换为你自己要访问的网址
[manager GET:@"https://api.github.com" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"responseObject:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"error.localDesc:%@", error.localizedDescription);
NSLog(@"%@", error);
}];
打印返回的数据将如下一般:
如果服务端使用的是正规CA签发的证书, 那么以下几行就可去掉:
NSSet <NSData *> *cerSet = [AFSecurityPolicy certificatesInBundle:[NSBundle mainBundle]];
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:cerSet];
policy.allowInvalidCertificates = YES;
manager.securityPolicy = policy;
采用默认的defaultPolicy
就可以了. AFN默认的securityPolicy就是它, 不必另写代码. AFSecurityPolicy类中会调用苹果security.framework的机制去自行验证本次请求服务端放回的证书是否是经过正规签名.