iOS封装HTTPS双向和单向验证

1.HttpsUtil

(1) 对双向和单向验证的封装

#import

#import "AFNetworking.h"


@interface HttpsUtil : NSObject


// 双向认证

+ (void)configHTTPSessionManager:(AFHTTPSessionManager *)manager serverCers:(NSArray *) serverCerNames clientP12:(NSString *) clientp12Name clientP12Password:(NSString *) clientP12Password isSelfCa:(BOOL) isSelfCa;


// 单向认证

+ (void)cconfigHTTPSessionManager:(AFHTTPSessionManager *)manager serverCers:(NSArray *) serverCerNames isSelfCa:(BOOL) isSelfCa;


@end

(2)实现方法

#import "HttpsUtil.h"


@implementation HttpsUtil


// 双向认证

+ (void)configHTTPSessionManager:(AFHTTPSessionManager *) manager serverCers:(NSArray *) serverCerNames clientP12:(NSString *) clientp12Name clientP12Password:(NSString *) clientP12Password isSelfCa:(BOOL) isSelfCa{

    

    __weakAFHTTPSessionManager*_manager = manager;

    

    if(!_manager){

        return;

    }

    

    NSMutableSet * serverCerDatas= [[NSMutableSetalloc] init];

    

    for (NSString * serverCerNamein serverCerNames){

        if(!serverCerName){

            continue;

        }

        NSString *cerPath = [[NSBundlemainBundle] pathForResource:serverCerNameofType:nil];// 证书的路径

        NSData *certData = [NSDatadataWithContentsOfFile:cerPath];

        [serverCerDatas addObject:certData];

    };

    

    _manager.securityPolicy.pinnedCertificates=serverCerDatas;

    

    // 需要验证客户端证书(双向认证)

    if(clientp12Name && clientP12Password){

        

        [manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession*session,NSURLAuthenticationChallenge *challenge,NSURLCredential *__autoreleasing*_credential) {

            

            NSURLSessionAuthChallengeDisposition disposition =NSURLSessionAuthChallengePerformDefaultHandling;

            

            __autoreleasingNSURLCredential *credential =nil;

            

            if([challenge.protectionSpace.authenticationMethodisEqualToString:NSURLAuthenticationMethodServerTrust]) {

                

                if([_manager.securityPolicyevaluateServerTrust:challenge.protectionSpace.serverTrustforDomain:challenge.protectionSpace.host]){

                    

                    credential = [NSURLCredentialcredentialForTrust:challenge.protectionSpace.serverTrust];

                    

                    if(credential) {

                        disposition =NSURLSessionAuthChallengeUseCredential;

                    } else {

                        disposition =NSURLSessionAuthChallengePerformDefaultHandling;

                    }

                } else {

                    disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;

                }

            } else {

                // client authentication

                SecIdentityRef identity =NULL;

                SecTrustRef trust =NULL;

                NSString *p12Path = [[NSBundlemainBundle] pathForResource:clientp12NameofType:nil];

                NSFileManager *fileManager =[NSFileManagerdefaultManager];

                

                if(![fileManagerfileExistsAtPath:p12Path]){

                    NSLog(@"客户端证书不存在!");

                } else {

                    NSData *PKCS12Data = [NSDatadataWithContentsOfFile:p12Path];

                    

                    if ([[selfclass]extractIdentity:&identityandTrust:&trust fromPKCS12Data:PKCS12Datapkcs12Password:clientP12Password]) {

                        NSLog(@"加载客户端证书成功");

                        SecCertificateRef certificate =NULL;

                        SecIdentityCopyCertificate(identity, &certificate);

                        constvoid*certs[] = {certificate};

                        CFArrayRef certArray =CFArrayCreate(kCFAllocatorDefault, certs,1,NULL);

                        credential =[NSURLCredentialcredentialWithIdentity:identitycertificates:(__bridge NSArray*)certArraypersistence:NSURLCredentialPersistencePermanent];

                        disposition =NSURLSessionAuthChallengeUseCredential;

                    }

                }

            }

            *_credential = credential;

            return disposition;

        }];

    }

    

    if(isSelfCa){

        manager.securityPolicy.allowInvalidCertificates =YES;

        manager.securityPolicy.validatesDomainName=NO;

            }else{

        // 注释掉Info.plist中整个NSAppTransportSecurity节点的配置

    }

}


// 单向认证

+ (void)cconfigHTTPSessionManager:(AFHTTPSessionManager *)manager serverCers:(NSArray *) serverCerNames isSelfCa:(BOOL) isSelfCa{

    

    [[selfclass]configHTTPSessionManager:managerserverCers:serverCerNamesclientP12:nilclientP12Password:nilisSelfCa:isSelfCa];

}


// 解压初始化客户端证书

+ (BOOL)extractIdentity:(SecIdentityRef*)outIdentity andTrust:(SecTrustRef *)outTrust fromPKCS12Data:(NSData *)inPKCS12Data pkcs12Password:(NSString *) p12Password{

    

    OSStatus securityError =errSecSuccess;

    

    NSDictionary* optionsDictionary = [NSDictionarydictionaryWithObject:p12PasswordforKey:(__bridgeid)kSecImportExportPassphrase];

    

    CFArrayRef items =CFArrayCreate(NULL,0, 0,NULL);

    securityError = SecPKCS12Import((__bridgeCFDataRef)inPKCS12Data,(__bridgeCFDictionaryRef)optionsDictionary,&items);

    

    if(securityError ==0) {

        // 成功

        CFDictionaryRef myIdentityAndTrust =CFArrayGetValueAtIndex(items,0);

        constvoid*tempIdentity =NULL;

        tempIdentity= CFDictionaryGetValue (myIdentityAndTrust,kSecImportItemIdentity);

        *outIdentity = (SecIdentityRef)tempIdentity;

        constvoid*tempTrust =NULL;

        tempTrust = CFDictionaryGetValue(myIdentityAndTrust,kSecImportItemTrust);

        *outTrust = (SecTrustRef)tempTrust;

    } else {

        NSLog(@"初始化客户端证书失败,errorCode:%d",(int)securityError);

        returnNO;

    }

    returnYES;

}


@end

/////////////////////////////////////////////////////////////////////////////
2.HttpsHandler   对网络请求的封装(get请求,post请求,post图片上传)

////////////////////////////////////////////////////////////////

#import

#import "AFNetworking.h"


@interface HttpsHandler : NSObject


+ (void)GET:(NSString *)URLString parameters:(id)patameters success:(void (^)(id responseObject))success failure:(void (^)(NSError *error))failure;

+ (void)POST:(NSString *)URLString parameters:(id)patameters success:(void (^)(id responseObject))success failure:(void (^)(NSError *error))failure;

+ (void)POST:(NSString *)URLString parameters:(id)patameters constructingBodyWithBlock:(void (^) (id <AFMultipartFormData> formData))block success:(void (^)(id responseObject))success failure:(void (^)(NSError *error))failure;


@end


//////////////////////////////////////////////////////////////////

#import "HttpsHandler.h"

#import "HttpsUtil.h"


@implementation HttpsHandler


+ (void)GET:(NSString *)URLString parameters:(id)patameters success:(void (^)(id))success failure:(void (^)(NSError *))failure {

    

    AFHTTPSessionManager *manager =[AFHTTPSessionManagermanager];

    

    NSArray *serverCersNames = [[NSArrayalloc] initWithObjects:@"mykey.cer",nil];

    [HttpsUtilconfigHTTPSessionManager:managerserverCers:serverCersNamesclientP12:@"mykey.p12"clientP12Password:@"password"isSelfCa:true];// 使用自签名CA给服务器server证书签名的isSelfCa为true,第三方权威CA签名的isSelfCa为false,当设置isSelfCa为false时,需要注释掉Info.plist中整个NSAppTransportSecurity节点的配置

    manager.responseSerializer = [AFHTTPResponseSerializerserializer];

    manager.requestSerializer.timeoutInterval =60.0f;

     manager.responseSerializer = [AFJSONResponseSerializerserializer];//申明返回的结果是json类型

    [manager.requestSerializersetValue:@"Content-Type"forHTTPHeaderField:@"application/json; charset=utf-8"];

    manager.responseSerializer.acceptableContentTypes = [NSSetsetWithObjects:@"application/json",@"text/json", @"text/javascript",@"text/html",nil];

    [manager GET:URLStringparameters:patameters progress:nilsuccess:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {

        if (success)

        {

            success(responseObject);

        }

    } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {

        if (failure)

        {

            failure(error);

            return ;

        }

    }];

    

}


+ (void)POST:(NSString *)URLString parameters:(id)patameters success:(void (^)(id))success failure:(void (^)(NSError *))failure {

    

    AFHTTPSessionManager *manager =[AFHTTPSessionManagermanager];

    /*

    NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"214051022010694" ofType:@"key"];

    NSData *cerData = [NSData dataWithContentsOfFile:cerPath];

    NSLog(@"%@",cerData);

    manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey withPinnedCertificates:[[NSArray alloc] initWithObjects:cerData, nil]];

    manager.securityPolicy.allowInvalidCertificates = YES;

    [manager.securityPolicy setValidatesDomainName:NO];

    manager.requestSerializer = [AFJSONRequestSerializer serializer];

    manager.responseSerializer = [AFJSONResponseSerializer serializer];

    */

  

    NSArray *serverCersNames = [[NSArrayalloc] initWithObjects:@"mykey.cer",nil];

    [HttpsUtilconfigHTTPSessionManager:managerserverCers:serverCersNamesclientP12:@"mykey.p12"clientP12Password:@"password"isSelfCa:true];// 使用自签名CA给服务器server证书签名的isSelfCa为true,第三方权威CA签名的isSelfCa为false,当设置isSelfCa为false时,需要注释掉Info.plist中整个NSAppTransportSecurity节点的配置

    manager.requestSerializer.timeoutInterval =60.0f;

    manager.requestSerializer = [AFHTTPRequestSerializerserializer];//表明请求的是json

    manager.responseSerializer = [AFJSONResponseSerializerserializer];//申明返回的结果是json类型

    [manager.requestSerializersetValue:@"Content-Type"forHTTPHeaderField:@"charset=utf-8"];

    manager.responseSerializer.acceptableContentTypes = [NSSetsetWithObjects:@"application/json",@"text/json", @"text/javascript",@"text/html",@"text/xml",nil];

    

    [manager.requestSerializersetValue:@"Content-Type"forHTTPHeaderField:@"charset=utf-8"];

    manager.responseSerializer.acceptableContentTypes = [NSSetsetWithObjects:@"application/json",@"text/json", @"text/javascript",@"text/html",@"text/xml",nil];

    [manager POST:URLStringparameters:patameters progress:nilsuccess:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {

        if (success)

        {

            success(responseObject);

        }

    } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {

        if (failure)

        {

            failure(error);

        }

    }];

}



+ (void)POST:(NSString *)URLString parameters:(id)patameters constructingBodyWithBlock:(void (^)(id))block success:(void (^)(id))success failure:(void (^)(NSError *))failure {

    

    AFHTTPSessionManager *manager =[AFHTTPSessionManagermanager];

    

    NSArray *serverCersNames = [[NSArrayalloc] initWithObjects:@"mykey.cer",nil];

    [HttpsUtilconfigHTTPSessionManager:managerserverCers:serverCersNamesclientP12:@"mykey.p12"clientP12Password:@"password"isSelfCa:true];// 使用自签名CA给服务器server证书签名的isSelfCa为true,第三方权威CA签名的isSelfCa为false,当设置isSelfCa为false时,需要注释掉Info.plist中整个NSAppTransportSecurity节点的配置

    manager.responseSerializer = [AFHTTPResponseSerializerserializer];

    manager.requestSerializer.timeoutInterval =60.0f;

     manager.requestSerializer = [AFHTTPRequestSerializerserializer];//表明请求的是json

     manager.responseSerializer = [AFJSONResponseSerializerserializer];//申明返回的结果是json类型

     [manager.requestSerializersetValue:@"application/json"forHTTPHeaderField:@"Content-Type"];

    [manager.requestSerializersetValue:@"application/json"forHTTPHeaderField:@"Accept"];

    manager.responseSerializer.acceptableContentTypes = [NSSetsetWithObjects:@"application/json",@"text/json", @"text/javascript",@"text/html,@“text/plain",nil];

    [manager POST:URLStringparameters:patameters constructingBodyWithBlock:^(id<AFMultipartFormData_Nonnull formData) {

       if (block)

       {

           block(formData);

       }

    } progress:nilsuccess:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {

       if (success)

       {

           success(responseObject);

       }

    } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {

       if (failure)

       {

           failure(error);

       }

    }];

    

}


//+ (NSString*)dataToJsonString:(id)object

//{

//    NSString *jsonString = nil;

//    NSError *error;

//    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object

//                                                       options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string

//                                                         error:&error];

//    if (! jsonData) {

//        NSLog(@"Got an error: %@", error);

//    } else {

//        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

//    }

//    return jsonString;

//}








@end



你可能感兴趣的:(iOS封装HTTPS双向和单向验证)