English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Principio di autenticazione del certificato di firma selvaggio HTTPS e l'encapsulation della richiesta dei dati in iOS

Sommario: Durante la conferenza degli sviluppatori WWDC 2016, Apple ha annunciato una scadenza: entro il 1° gennaio 2017, tutte le applicazioni presenti sull'App Store devono attivare la funzione di sicurezza App Transport Security (ATS). App Transport Security (ATS) è una funzione di protezione della privacy introdotta da Apple con iOS 9, che blocca il caricamento delle risorse HTTP in chiaro e richiede che le connessioni passino attraverso HTTPS, un protocollo più sicuro. Al momento, Apple permette agli sviluppatori di disattivare temporaneamente l'ATS, continuando a utilizzare connessioni HTTP, ma entro la fine dell'anno tutte le applicazioni degli store ufficiali devono utilizzare obbligatoriamente l'ATS.

Il framework utilizzato nel progetto è AFNetworking versione 3.0 o superiore, a causa di ATS, iOS consente solo l'uso di collegamenti che iniziano con Https, Apple ha permesso di aggirare ATS prima del 30 dicembre 2016, come mostrato nell'immagine seguente:

Ma partire dal 1° gennaio 2017, non verranno più accettate applicazioni che utilizzano http per caricare risorse. Pertanto, questo articolo spiega come utilizzare AFN per ottenere l'autenticazione di certificati di firma selvaggio (Nota: non è necessario autenticare certificati certificati da CA; è possibile utilizzare direttamente collegamenti che iniziano con Https per accedere ai dati e caricare le pagine). Il progetto è stato caricato su GitHub (per riferimento al codice sorgente, fare clic sul link):HttpsSignatureCertificate_jb51.rar

1,建立一个根类 此处命名为AKNetPackegeAFN

 1> .h文件,创建所需要的Get 与 Post 方法

#import <Foundation/Foundation.h>
typedef enum{
  AKNetWorkGET ,  /**< GET请求 */
  AKNetWorkPOST = 1 /**< POST请求 */
};AKNetWorkType;
typedef void (^HttpSuccess)(id json);
typedef void (^HttpErro)(NSError* error);
@interface AKNetPackegeAFN : NSObject
(instancetype)shareHttpManager;
/*
 *
 netWorkType:metodo di richiesta GET o POST
 signature:se utilizzare il certificato di firma, inserire direttamente il nome del certificato, altrimenti inserire nil
 api:interfaccia URL della richiesta
 parameters:parametri della richiesta
 sucess:valore di ritorno in caso di successo della richiesta
 fail:valore di ritorno in caso di fallimento della richiesta
 *
 */
- (void)netWorkType:(AKNetWorkType)netWorkType Signature:(NSString *)signature API:(NSString *)api Parameters:(NSDictionary *)parameters Success:(HttpSuccess)sucess Fail:(HttpErro)fail;
@end

2> .m文件,导入头文件AFNetworking.h 新建Manager 属性并实现shareHttpManager类方法

#import "AKNetPackegeAFN.h"
#import "AFNetworking.h"
@interface AKNetPackegeAFN()
@property (nonatomic,strong) AFHTTPSessionManager *manager;
@end
@implementation AKNetPackegeAFN
+(instancetype)shareHttpManager{
  static dispatch_once_t onece = 0;
  static AKNetPackegeAFN *httpManager = nil;
  dispatch_once(&onece, ^(void){
    httpManager = [[self alloc]init];
  });
  return httpManager;
}

2,Get 与 Post 方法的实现

使用时将后台所给的证书转换为 .cer 格式拖入项目根目录中,在方法中进行绑定即可。例如后台给的证书名为:Kuture.crt。收到证书后双击进行安装,然后打开钥匙串,将名为 Kuture 的证书右击导出,选择后缀为 .cer 然后确定即可。如下图所示:

  --> -->

-->

GET 与 POST 实现方法的封装

- (void)netWorkType:(AKNetWorkType)netWorkType Signature:(NSString *)signature API:(NSString *)api Parameters:(NSDictionary *)parameters Success:(HttpSuccess)sucess Fail:(HttpErro)fail{
  //开启证书验证模式
  AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
  //是否允许使用自签名证书
  signature == nil ? (void)(securityPolicy.allowInvalidCertificates = NO) : (securityPolicy.allowInvalidCertificates = YES);
  //Deve verificare o meno il nome del dominio
  securityPolicy.validatesDomainName = NO;
  _manager = [[AFHTTPSessionManager alloc]initWithBaseURL:[NSURL URLWithString:api]];
  _manager.responseSerializer = [AFJSONResponseSerializer serializer];
  _manager.securityPolicy = securityPolicy;
  _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"application/xml",@"text/xml",@"text/json",@"text/plain",@"text/javascript",@"text/html", nil];
  se (signature != nil){
    __weak typeof(self) weakSelf = self;
    [_manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential *__autoreleasing *_credential) {
      //Ottento l'oggetto di fiducia del server
      SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
      //Importazione del certificato di firma
      NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"il nome del tuo certificato" ofType:@"cer"];
      NSData *cerData = [NSData dataWithContentsOfFile:cerPath];
      se non (!cerData) {
        NSLog(@"==== Il file .cer è nil ====");
        return 0;
      }
      NSArray *cerArray = @[cerData];
      weakSelf.manager.securityPolicy.pinnedCertificates = cerArray;
      SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)cerData);
      NSCAssert(caRef != nil, @"caRef è nil");
      NSArray *caArray = @[(__bridge id)(caRef)];
      NSCAssert(caArray != nil, @"caArray è nil");
      //Impostare il certificato letto come il certificato radice di serverTrust
      OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);
      SecTrustSetAnchorCertificatesOnly(serverTrust, NO);
      NSCAssert(errSecSuccess == status, @"SectrustSetAnchorCertificates failed");
      //Scegliere il modo di gestione dell'autenticazione di interrogazione
      NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
      __autoreleasing NSURLCredential *credential = nil;
      //Modalità di autenticazione di interrogazione NSURLAuthenTicationMethodServerTrust
      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        //Basato delle politiche di sicurezza del client per determinare se fidarsi del server, se non si fida non risponde all'interrogazione
        if ([weakSelf.manager.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
          //Crea il certificato di sfida
          credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
          //Conferma il metodo di sfida
          if (credential) {
            disposition = NSURLSessionAuthChallengeUseCredential;
          } else {
            disposition = NSURLSessionAuthChallengePerformDefaultHandling;
          }
        } else {
          //Annulla la sfida
          disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
        }
      } else {
        disposition = NSURLSessionAuthChallengePerformDefaultHandling;
      }
      return disposition;
    };
  }
  if (netWorkType == 0){
    [_manager GET:api parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
    } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
      if (sucess){
        sucess(responseObject);
      }else{
        NSLog(@"Connessione fallita o rete non esistente");
      }
    failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
      fail(error);
    };
  }else if (netWorkType == 1){
    [_manager POST:api parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
    } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
      if (sucess){
        sucess(responseObject);
      }else{
        NSLog(@"Connessione fallita o rete non esistente");
      }
    failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
      fail(error);
    };
  }  
}

2 Uso, direttamente nell'oggetto che necessita di ottenere o trasmettere dati, importare il file header AKNetPackegeAFN.h e implementare il metodo, come indicato di seguito:

//Creazione dell'oggetto
  //Se è un certificato di firma autogenerato, prima di usarlo, esegui il binding del certificato nel metodo corrispondente di AKNetPackegeAFN (il certificato può essere trascinato direttamente nel progetto)
  /*
   *
   netWorkType:metodo di richiesta GET o POST
   signature:se utilizzare il certificato di firma, inserire direttamente il nome del certificato, altrimenti inserire nil
   api:interfaccia URL della richiesta
   parameters:parametri della richiesta
   sucess:valore di ritorno in caso di successo della richiesta
   fail:valore di ritorno in caso di fallimento della richiesta
   *
   */
  AKNetPackegeAFN *netHttps = [AKNetPackegeAFN shareHttpManager];
  [netHttps netWorkType:类型 di richiesta Signature:nome del certificato API:URL della richiesta Parameters:parametri Success:^(id json) {
    NSLog(@"Json:%@",json);
  }; Fail:^(NSError *error) {
    NSLog(@"Error:%@",error);
  };

Questo è tutto il contenuto dell'articolo, speriamo che sia utile per il tuo studio e che tu sostenga fortemente la guida a urla.

Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, il copyright spetta agli autori, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non possiede i diritti di proprietà, non è stato elaborato manualmente e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, è gradito inviare una e-mail a notice#oldtoolbag.com (sostituisci # con @ durante l'invio dell'e-mail) per segnalare, fornendo prove pertinenti. Una volta verificata, questo sito rimuoverà immediatamente il contenuto sospetto di violazione del copyright.

Ti potrebbe interessare