SDWebImage 加载Https自签名证书图片
你是否遇到了这种情况,好不容易AFN 访问https接口成功了但是图片加载不出来?传了
SDWebImageAllowInvalidSSLCertificates 没效果(这种情况只适用于CA我觉得),
网上众多的在SDWebimageDownloader.m
中添加URLSession代理方法也不行 如果是下面这种和我遇到了同样的问题 请接着看
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
NSLog(@"证书认证");
if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust]) {
do{
SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
NSCAssert(serverTrust != nil, @"serverTrust is nil");
if(nil == serverTrust) break;
/* failed */
/**
* 导入多张CA证书(Certification Authority,支持SSL证书以及自签名的CA),请替换掉你的证书名称
*/
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"证书名字_cerName" ofType:@"cer"];
//自签名证书
NSData* caCert = [NSData dataWithContentsOfFile:cerPath];
NSCAssert(caCert != nil, @"caCert is nil");
if(nil == caCert) break;
/* failed */
SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCert);
NSCAssert(caRef != nil, @"caRef is nil");
if(nil == caRef) break;
/* failed */
//可以添加多张证书
NSArray *caArray = @[(__bridge id)(caRef)];
NSCAssert(caArray != nil, @"caArray is nil");
if(nil == caArray) break;
/* failed */
//将读取的证书设置为服务端帧数的根证书
OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);
NSCAssert(errSecSuccess == status, @"SecTrustSetAnchorCertificates failed");
if(!(errSecSuccess == status)) break;
/* failed */
SecTrustResultType result = -1;
//通过本地导入的证书来验证服务器的证书是否可信
status = SecTrustEvaluate(serverTrust, &result);
if(!(errSecSuccess == status)) break;
/* failed */
NSLog(@"stutas:%d",(int)status);
NSLog(@"Result: %d", result);
BOOL allowConnect = (result == kSecTrustResultUnspecified) || (result == kSecTrustResultProceed);
if (allowConnect) {
NSLog(@"success");
}else {
NSLog(@"error");
}
/* kSecTrustResultUnspecified and kSecTrustResultProceed are success */
if(! allowConnect) {
break;
/* failed */
}
#if 0
/*
Treat kSecTrustResultConfirm and kSecTrustResultRecoverableTrustFailure as success
*/
/* since the user will likely tap-through to see the dancing bunnies */
if(result == kSecTrustResultDeny || result == kSecTrustResultFatalTrustFailure || result == kSecTrustResultOtherError) break;
/* failed to trust cert (good in this case) */
#endif
// The only good exit point
NSLog(@"信任该证书");
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
return [[challenge sender] useCredential: credential forAuthenticationChallenge: challenge
];
}while(0);
}
// Bad dog
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,credential);
return [[challenge sender] cancelAuthenticationChallenge: challenge];
}
却总是
证书认证
stutas:0
Result: 5
error
不明就理?
是否觉得后台没有升级TSL1.2有问题但是后台说没有坚持不下?
看这里。。。。
我们用AFN的代码来验证证书不就好了,为了不改动 SDWebimageDownloader.m的源码避免以后升级出错我们建个分类
.h
#import "SDWebImageDownloader+AFNhttps.h"
@interface SDWebImageDownloader (AFNhttps)<NSURLSessionDelegate>
@end
.m
#import <AFNetworking.h>
#import <SDWebImageDownloader.h>
#import "SDWebImageDownloader+AFNhttps.h"
@implementation SDWebImageDownloader (AFNhttps)
+(AFSecurityPolicy *)customSecurityPolicy {
//先导入证书到项目
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"你的证书" ofType:@"cer"];//证书的路径
NSData *cerData = [NSData dataWithContentsOfFile:cerPath];
//AFSSLPinningModeCertificate使用证书验证模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
//如果是需要验证自建证书,需要设置为YES
securityPolicy.allowInvalidCertificates = YES;
//validatesDomainName 是否需要验证域名,默认为YES;
securityPolicy.validatesDomainName = NO;
NSSet *cerDataSet = [NSSet setWithArray:@[cerData]];
securityPolicy.pinnedCertificates = cerDataSet;
return securityPolicy;
}
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
NSLog(@"证书认证");
SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
[[SDWebImageDownloader customSecurityPolicy]evaluateServerTrust:serverTrust forDomain:nil];
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling,credential);
return [[challenge sender] useCredential: credential
forAuthenticationChallenge: challenge];
}
@end
就这样用AFN的代码验证SDWebImage的https图片了