2016-12-21 7 views
6

я ниже код сертификата pinning in AndroidСертификат пиннинга в Xcode

CertificatePinner certificatePinner = new CertificatePinner.Builder() 
.add("publicobject.com", "sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=") 
.add("publicobject.com", "sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=") 
.add("publicobject.com", "sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=") 
.add("publicobject.com", "sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=") 
.build(); 

Как я достичь той же задачи в IOS с использованием метода NSURLSession?

Есть некоторый код ссылки здесь

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{ 
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; 
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0); 
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); 
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"MyLocalCertificate" ofType:@"cer"]; 
NSData *localCertData = [NSData dataWithContentsOfFile:cerPath]; 
if ([remoteCertificateData isEqualToData:localCertData]) { 
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust]; 
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 
} 
else { 
[[challenge sender] cancelAuthenticationChallenge:challenge]; 
} 

EDIT ЧАСТЬ

я ниже решения, которое функция делегата вызывается автоматически в NSURLSession, может кто-нибудь объяснить, как это будет работать? ТАКЖЕ Нужно отправить сертификат мультипликатора, как мне это сделать?

(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler 
{ 
    NSString *authMethod = [[challenge protectionSpace] authenticationMethod]; 

    if ([authMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { 

     NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; 
     completionHandler(NSURLSessionAuthChallengeUseCredential,credential); 
    } else { 
     SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; 
     SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0); 
     NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); 
     NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"MyLocalCertificate" ofType:@"cer"]; 
     NSData *localCertData = [NSData dataWithContentsOfFile:cerPath]; 
     NSURLCredential *credential; 

     if ([remoteCertificateData isEqualToData:localCertData]) { 
      credential = [NSURLCredential credentialForTrust:serverTrust]; 
      [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 
     } 
     else { 
      [[challenge sender] cancelAuthenticationChallenge:challenge]; 
     } 



     completionHandler(NSURLSessionAuthChallengeUseCredential, credential); 
     NSLog(@"Finished Challenge"); 
    } 
} 
+0

Я думаю, что многие разработчики iOS не знакомы с Android. – KudoCC

+0

мне тоже ...: D lol нужно сделать аналогичный код для IOS по требованию клиента – iphonemaclover

+1

Вы посмотрели Alamofire - это ручка закрепления https://github.com/Alamofire/Alamofire – Flexicoder

ответ

1

Условный блок пропускает сертификат пиннинга, если метод аутентификации NSURLAuthenticationMethodServerTrust. Я не совсем уверен, почему вы это сделаете - вам придется посмотреть на источник, где вы получили этот фрагмент кода и посмотреть, что это за требования.

Если метод аутентификации - это что-то еще, блок else выполняет привязку сертификата.

Переменная serverTrust отправляется в состояние транзакции SSL с сервера. Главное здесь, что у него есть цепочка сертификатов, которые аутентифицируют сервер. В следующей строке certificate устанавливается в сертификат листа в цепочке, то есть сертификат сервера.

remoteCertificateData по существу является большим двоичным блобом, представляющим информацию в сертификате. Для управления памятью необходим вызов CFBridgingRelease (все функции CFxxx - это функции C/C++, а не Objective-C, а управление памятью немного сложнее, чем обычно).

localCertData - это двоичный код информации в местной копии сертификата. Обратите внимание, что приложения iOS представляют собой (более или менее) набор файлов, включая исполняемый файл, а также различные ресурсы и т. Д. В рамках процесса сборки вы должны организовать копирование сертификата сервера, который будет включен в коллекцию (NSBundle) файлов. Переменная cerPath устанавливается в путь к файлу локальной копии сертификата.

Наконец, мы проверяем, равны ли две бинарные ячейки. Если нет, то сертификат с сервера является фиктивным, и мы не будем продолжать запрос.

Я не совсем уверен, что вы подразумеваете под «Необходимость отправки свидетельства мультипликатора». Судя по Java-коду, на котором вы ссылаетесь, я предполагаю, что вы имеете в виду, что вы хотите сравнить сертификат сервера с несколькими локальными сертификатами. В этом случае что-то (примерно) следующее (примечание: непроверенный код):

SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; 
    SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0); 
    NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); 

    BOOL match = NO; 
    NSURLCredential *credential; 

    for (NSString *path in [[NSBundle mainBundle] pathsForResourcesOfType:@"cer" inDirectory:@"."]) { 
      NSData *localCertData = [NSData dataWithContentsOfFile:path]; 

      if ([remoteCertificateData isEqualToData:localCertData]) { 
       credential = [NSURLCredential credentialForTrust:serverTrust]; 
       match = YES; 
       break; 
      } 
    }  

    if (match) { 
     [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 
    } else { 
     [[challenge sender] cancelAuthenticationChallenge:challenge]; 
    } 

    completionHandler(NSURLSessionAuthChallengeUseCredential, credential); 
    NSLog(@"Finished Challenge"); 
Смежные вопросы