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
////////////////////////////////////////////////////////////////
#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
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