1. 程式人生 > >iOS HTTPS證書不受信任解決辦法

iOS HTTPS證書不受信任解決辦法

寫在前面: 如果看完這篇文章對你有所幫助,並且你自認為比較熱愛學習,那麼請移步《全棧技術交流群歡迎你》,加入我們,一起學習

之前開發App的時候服務端使用的是自簽名的證書,導致iOS開發過程中呼叫HTTPS介面時,證書不被信任

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{

    /*方法一*/
if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){ NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; if(completionHandler) completionHandler(NSURLSessionAuthChallengeUseCredential,credential); } /*方法二*/
// SecTrustRef servertrust = challenge.protectionSpace.serverTrust; // SecCertificateRef certi= SecTrustGetCertificateAtIndex(servertrust, 0); // NSData *certidata = CFBridgingRelease(CFBridgingRetain(CFBridgingRelease(SecCertificateCopyData(certi)))); // NSString *path = [[NSBundle mainBundle] pathForResource:@"證書名稱" ofType:@"cer"];
//// NSLog(@"證書 : %@",path); // NSData *localCertiData = [NSData dataWithContentsOfFile:path]; // if ([certidata isEqualToData:localCertiData]) { // NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:servertrust]; // [challenge.sender useCredential:credential forAuthenticationChallenge:challenge]; // completionHandler(NSURLSessionAuthChallengeUseCredential, credential); //// NSLog(@"服務端證書認證通過"); // }else { // completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); // NSLog(@"服務端認證失敗"); // } }

這裡有兩個方法,第一個是信任所有證書,第二個是把服務端自簽名的證書放到本地,類似白名單的樣子去載入

原始碼

HttpRequest.h

//
//  HttpRequest.h
//
//  Created by Michael Zhan on 2017/5/17.
//  Copyright © 2017年 Michael Zhan. All rights reserved.
//

#import <Foundation/Foundation.h>

static NSString * const baseUrl = @"http://";

typedef void (^SuccessBlock)(NSString * data);
typedef void (^FailureBlock)(NSError * error);

@interface HttpRequest : NSObject <NSURLSessionTaskDelegate>

- (void)getWithDict:(NSString *)paramUrl NSDictionary:(NSDictionary *)paramDicet success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock;

- (void)postWithDict:(NSString *)paramUrl NSDictionary:(NSDictionary *)paramDicet success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock;

- (void)getWithString:(NSString *)paramUrl NSString:(NSString *)paramString success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock;

- (void)postWithString:(NSString *)paramUrl NSString:(NSString *)paramString success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock;

- (void)postWithDict2String:(NSString *)paramUrl NSDictionary:(NSDictionary *)paramDicet success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock;

@end

HttpRequest.m

//
//  HttpRequest.m
//
//  Created by Michael Zhan on 2017/5/17.
//  Copyright © 2017年 Michael Zhan. All rights reserved.
//

#import "HttpRequest.h"

@implementation HttpRequest

- (void)getWithDict:(NSString *)paramUrl NSDictionary:(NSDictionary *)paramDicet success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock{

    NSMutableString * mutableStringUrl = [[NSMutableString alloc] initWithString:paramUrl];
    [mutableStringUrl appendString:[HttpRequest convertToJsonData:paramDicet]];

    NSLog(@"url %@",mutableStringUrl);

    NSURL * url = [NSURL URLWithString:[mutableStringUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];

    NSURLRequest * request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];

    //2程式自動安裝證書的方式
    NSURLSession * session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];

    NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            failureBlock(error);
        } else {
            NSString * result = [[NSString alloc] initWithData:data  encoding:NSUTF8StringEncoding];
            successBlock(result);
        }
    }];
    [dataTask resume];

}

- (void)postWithDict:(NSString *)paramUrl NSDictionary:(NSDictionary *)paramDicet success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock{

    NSURL * url = [NSURL URLWithString:paramUrl];

    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url
                    cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:100];

    request.HTTPMethod = @"POST";
    NSString * jsonStr = [HttpRequest convertToJsonData:paramDicet];
    request.HTTPBody = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];

    //2程式自動安裝證書的方式
    NSURLSession * session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];

    NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            failureBlock(error);
            [session finishTasksAndInvalidate];
        } else {
            NSString * result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            successBlock(result);
            [session finishTasksAndInvalidate];
        }
    }];
    [dataTask resume];
}

- (void)postWithDict2String:(NSString *)paramUrl NSDictionary:(NSDictionary *)paramDicet success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock{

    NSURL * url = [NSURL URLWithString:paramUrl];

    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:100];

    request.HTTPMethod = @"POST";
    NSString * jsonStr = [NSString stringWithFormat:@"%@",paramDicet];
    request.HTTPBody = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    request.timeoutInterval = 10;
    request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;


    //2程式自動安裝證書的方式
    NSURLSession * session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];

    NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            failureBlock(error);
            [session finishTasksAndInvalidate];
        } else {
            NSString * result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            successBlock(result);
            [session finishTasksAndInvalidate];
        }
    }];
    [dataTask resume];
}

- (void)getWithString:(NSString *)paramUrl NSString:(NSString *)paramString success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock{

    NSMutableString * mutableStringUrl = [[NSMutableString alloc] initWithString:paramUrl];
    [mutableStringUrl appendString:paramString];

    NSLog(@"url %@",mutableStringUrl);
    NSURL * url =[NSURL URLWithString:[mutableStringUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];

    NSURLRequest * request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];

    //2程式自動安裝證書的方式
    NSURLSession * session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];

    NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            failureBlock(error);
            [session finishTasksAndInvalidate];
        } else {
            NSString * result = [[NSString alloc] initWithData:data  encoding:NSUTF8StringEncoding];
            successBlock(result);
            [session finishTasksAndInvalidate];
        }
    }];
    [dataTask resume];

}

- (void)postWithString:(NSString *)paramUrl NSString:(NSString *)paramString success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock{

    NSURL * url = [NSURL URLWithString:paramUrl];

    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:100];
    request.HTTPMethod = @"POST";
    request.HTTPBody = [paramString dataUsingEncoding:NSUTF8StringEncoding];
    request.timeoutInterval = 10;
    request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;

    //2程式自動安裝證書的方式
    NSURLSession * session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];

    NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            failureBlock(error);
             [session finishTasksAndInvalidate];
        } else {
            NSString * result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            successBlock(result);
             [session finishTasksAndInvalidate];
        }
    }];
    [dataTask resume];
}

+ (NSString *)convertToJsonData:(NSDictionary *)dict{
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
    NSString *jsonString;
    if (!jsonData) {
        NSLog(@"%@",error);
    }else{
        jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
    NSRange range = {0,jsonString.length};
    //去掉字串中的空格
    [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
    NSRange range2 = {0,mutStr.length};
    //去掉字串中的換行符
    [mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
    return mutStr;
}

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{

    /*方法一*/
    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){
        NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        if(completionHandler)
            completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
    }

    /*方法二*/
//    SecTrustRef servertrust = challenge.protectionSpace.serverTrust;
//    SecCertificateRef certi= SecTrustGetCertificateAtIndex(servertrust, 0);
//    NSData *certidata = CFBridgingRelease(CFBridgingRetain(CFBridgingRelease(SecCertificateCopyData(certi))));
//    NSString *path = [[NSBundle mainBundle] pathForResource:@"zwp" ofType:@"cer"];
////    NSLog(@"證書 : %@",path);
//    NSData *localCertiData = [NSData dataWithContentsOfFile:path];
//    if ([certidata isEqualToData:localCertiData]) {
//        NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:servertrust];
//        [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
//        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
////        NSLog(@"服務端證書認證通過");
//    }else {
//        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
//        NSLog(@"服務端認證失敗");
//    }

}

@end