2015-12-17 2 views
3

Я потратил некоторое время, пытаясь заставить это работать. У меня есть API, с которым я подключаюсь, и пытаюсь переключиться на SSL с самоподписанными сертификатами. У меня есть контроль над сервером и приложением.ios9 самозаверяющий сертификат и безопасность на транспорте приложения

Я создал самостоятельно подписанный сертификат в соответствии с этим:

https://kyup.com/tutorials/create-ssl-certificate-nginx/

sudo openssl genrsa -des3 -out ssl.key 2048 
sudo openssl req -new -key ssl.key -out ssl.csr 
sudo cp ssl.key ssl.key.orig & sudo openssl rsa -in ssl.key.orig -out ssl.key 
sudo openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt 

Я пробовал некоторые параметры конфигурации на сервере (Nginx)

ssl on; 
ssl_certificate /etc/nginx/ssl/ssl.crt; 
ssl_certificate_key /etc/nginx/ssl/ssl.key; 
ssl_session_timeout 5m; 
ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2; 
ssl_ciphers HIGH:!aNULL:!MD5; 
#ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"; 
ssl_prefer_server_ciphers on; 

И на клиенте сторона Я пробовал несколько разных вариантов с АТС:

<key>NSAppTransportSecurity</key> 
<dict> 
    <key>NSAllowsArbitraryLoads</key> 
    <true/> 
</dict> 

и

<key>NSAppTransportSecurity</key> 
<dict> 
    <key>NSAllowsArbitraryLoads</key> 
    <true/> 
    <key>NSExceptionDomains</key> 
    <dict> 
     <key>test.example.com (NOT REALLY MY DOMAIN)</key> 
     <dict> 
      <key>NSExceptionAllowsInsecureHTTPLoads</key> 
      <true/> 
     </dict> 
    </dict> 
</dict> 

и

<key>NSAppTransportSecurity</key> 
<dict> 
    <key>NSAllowsArbitraryLoads</key> 
    <true/> 
    <key>NSExceptionDomains</key> 
    <dict> 
     <key>test.example.com (NOT REALLY MY DOMAIN)</key> 
     <dict> 
      <key>NSExceptionAllowsInsecureHTTPLoads</key> 
      <true/> 
      <key>NSExceptionRequiresForwardSecrecy</key> 
      <false/> 
      <key>NSExceptionMinimumTLSVersion</key> 
      <string>TLSv1.1</string> 
     </dict> 
    </dict> 
</dict> 

В зависимости от различных вариантов ATS я получаю ошибки:

An SSL error has occurred and a secure connection to the server cannot be made. 

или

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) 
The certificate for this server is invalid. You might be connecting to a server that is pretending to be “MYDOMAIN” which could put your confidential information at risk. 

Любые идеи? Кто-нибудь еще сталкивается с самоподписанными сертификатами?

P.S. Я на OS X 10.11.2 Beta, Xcode 7.1.1

ответ

3

Я понял вопрос. Это не имеет ничего общего с App Transport Security. Я должен был удостовериться, что iOS доверяет сертификату, так как это не от доверенного органа.

Старая школа способ сделать это путем переопределения NSURLRequest.allowsAnyHTTPSCertificateForHost не работает.

Поскольку я использую NSURLSession вы должны сделать это с этим:

- (id) init { 
    self = [super init]; 
    NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration]; 
    self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]]; 
    return self; 
} 

- (void) URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { 
    completionHandler(NSURLSessionAuthChallengeUseCredential,[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); 
} 
+0

Куда мы добавить это. Также я использую гибридное приложение –

2

просто нужно добавить .cer к SecTrust

func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) { 

    if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) { 
     if let trust = challenge.protectionSpace.serverTrust, 
      let pem = Bundle.main.path(forResource: "https", ofType: "cer"), 
      let data = NSData(contentsOfFile: pem), 
      let cert = SecCertificateCreateWithData(nil, data) { 
      let certs = [cert] 
      SecTrustSetAnchorCertificates(trust, certs as CFArray) 

      completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: trust)) 
      return 
     } 
    } 

    // Pinning failed 
    completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil) 
}