iOS封装HTTPS双向和单向验证

news/2024/7/7 19:53:24

1.HttpsUtil

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

#import <Foundation/Foundation.h>

#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 <Foundation/Foundation.h>

#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<AFMultipartFormData>))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




http://lihuaxi.xjx100.cn/news/235240.html

相关文章

乐视云计算被列入失信名单;三星华为达成和解;Python3 采用率超 84%丨Q新闻

本周要闻&#xff1a;三星华为达成和解&#xff1b;乐视云计算被列入失信名单&#xff1b;小米宣布成立技术委员会&#xff1b;支付宝小程序向个人开发者开放公测&#xff1b;Flutter 1.2 发布&#xff1b;Python3 采用率超 84%&#xff1b;调查称最受雇主欢迎的语言是 Go&…

做一款仿映客的直播App?看我就够了

来源&#xff1a;JIAAIR 链接&#xff1a;http://www.jianshu.com/p/5b1341e97757 一、直播现状简介 1.技术实现层面&#xff1a; 技术相对都比较成熟&#xff0c;设备也都支持硬编码。IOS还提供现成的 Video ToolBox框架&#xff0c;可以对摄像头和流媒体数据结构进行处理&am…

OC封装时间选择器

#import <UIKit/UIKit.h> protocol TimeDatePickerViewDelegate <NSObject> //必须实现的两个协议 required - (void)changeTime : (NSDate *)date;//当时改变时出发 - (void)daterMine : (NSDate *)date;//更确定时间 end interface TimeDatePickerView :UIView /…

蓝桥杯 扑克序列(全排列)

扑克序列 A A 2 2 3 3 4 4&#xff0c; 一共4对扑克牌。请你把它们排成一行。要求&#xff1a;两个A中间有1张牌&#xff0c;两个2之间有2张牌&#xff0c;两个3之间有3张牌&#xff0c;两个4之间有4张牌。 请填写出所有符合要求的排列中&#xff0c;字典序最小的那个。 例如&a…

runLoop和runtime的分析

一.RunLoop: Runloop是事件接收和分发机制的一个实现。 Runloop提供了一种异步执行代码的机制&#xff0c;不能并行执行任务。 在主队列中&#xff0c;Main RunLoop直接配合任务的执行&#xff0c;负责处理UI事件、定时器以及其他内核相关事件。 (1).RunLoop的主要目的&#…

iOS弹幕(源码)实现原理解析

弹幕&#xff0c;国内流行于视频网站A站和B站。网上关于弹幕的实现方法有很多&#xff0c;目前Android平台已经有比较成熟的解决方案DanmakuFlameMaster 。而iOS平台尚无比较成熟的开源库&#xff0c;在借鉴DanmakuFlameMaster的实现思想后&#xff0c;特分享iOS平台弹幕解决方…

MediaCodeC解码视频指定帧,迅捷、精确

原创文章&#xff0c;转载请联系作者 若待明朝风雨过&#xff0c;人在天涯&#xff01;春在天涯 原文地址 提要 最近在整理硬编码MediaCodec相关的学习笔记&#xff0c;以及代码文档&#xff0c;分享出来以供参考。本人水平有限&#xff0c;项目难免有思虑不当之处&#xff0c;…

Golang在视频直播平台的高性能实践(含PPT下载)

熊猫 TV 是一家视频直播平台&#xff0c;先介绍下我们系统运行的环境&#xff0c;下面这 6 大服务只是我们几十个服务中的一部分&#xff0c;由于并发量与重要性比较高&#xff0c;所以成为 golang 小试牛刀的首批高性能高并发服务。 把大服务拆细&#xff0c; 然后服务化独立部…