2015-12-03 87 views
1

我有服務器證書和客戶端證書,需要包括在請求來驗證服務器是否有任何教程或引用,以迅速提出此類請求如何在swift中向服務器發出HTTPS請求?

我能夠在java中做到,但我是新來的SWIFT我想迅速的資源進行身份驗證並請求到服務器

我的Java代碼,使SSL配置:

SslConfigurator sslConfig = SslConfigurator.newInstance().securityProtocol("protocol") 
       .keyStoreFile("/path").keyStorePassword("password").keyStoreType("JKS") 
       .trustStoreFile("path"); 
+0

Swift本身不提供網絡API。也許你真的在問如何使用該平臺上的許多框架之一在iOS應用程序中建立SSL連接?嘗試仔細閱讀[Apple的開發者庫](https://developer.apple.com/library/prerelease/ios/navigation/#section=Topics&topic=Networking%20%26amp%3B%20Internet)。 – rickster

回答

6

我使用的是iOS原生庫。您可以使用下面的函數用於連接和服務器證書和客戶端證書身份驗證:

 func ConnectionRequest(jsonString:NSDictionary, callback: (NSDictionary, String!) -> Void) { 
    let request = NSMutableURLRequest(URL: NSURL(string: "https://example.com:9222")!) 

    var result = NSDictionary() 

    do { 
     request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(jsonString, options: []) 
    } catch{ 
     request.HTTPBody = nil 
    } 
    request.timeoutInterval = 20.0 //(number as! NSTimeInterval) 
    request.HTTPMethod = "POST" 
    request.setValue("application/json", forHTTPHeaderField: "Content-Type") 
    request.setValue("gzip", forHTTPHeaderField: "Accept-encoding") 

    let configuration = 
    NSURLSessionConfiguration.defaultSessionConfiguration() 

    let session = NSURLSession(configuration: configuration, 
     delegate: self, 
     delegateQueue:NSOperationQueue.mainQueue()) 
    print("--------------------------------NSURLSession Request-------------------------------------------------->:\n \(jsonString)") 
    print(NSDate()) 


    let task = session.dataTaskWithRequest(request){ 
     (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in 

     if let httpResponse = response as? NSHTTPURLResponse { 
      if httpResponse.statusCode != 200 { 
       print("response was not 200: \(response)") 
       return 
      } 
      else 
      { 
       print("response was 200: \(response)") 

       print("Data for 200: \(data)") 

       // In the callback you can return the data/response 
       callback(data, nil) 
       return 
      } 
     } 
     if (error != nil) { 
      print("error request:\n \(error)") 
      //Here you can return the error and handle it accordingly 
      return 
     } 

    } 
    task.resume() 

} 

以下是與在info.plist中完成自我簽名SSL證書

func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) { 

    if challenge.protectionSpace.authenticationMethod == (NSURLAuthenticationMethodServerTrust) { 


    let serverTrust:SecTrustRef = challenge.protectionSpace.serverTrust! 
    let certificate: SecCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)! 
    let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))! 
    let cerPath: String = NSBundle.mainBundle().pathForResource("example.com", ofType: "cer")! 
    let localCertificateData = NSData(contentsOfFile:cerPath)! 


     if (remoteCertificateData.isEqualToData(localCertificateData) == true) { 
      let credential:NSURLCredential = NSURLCredential(forTrust: serverTrust) 

      challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge) 


      completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)) 

     } else { 

      completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge, nil) 
     } 
    } 
    else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate 
    { 

     let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")! 
     let PKCS12Data = NSData(contentsOfFile:path)! 


     let identityAndTrust:IdentityAndTrust = self.extractIdentity(PKCS12Data); 



      let urlCredential:NSURLCredential = NSURLCredential(
       identity: identityAndTrust.identityRef, 
       certificates: identityAndTrust.certArray as? [AnyObject], 
       persistence: NSURLCredentialPersistence.ForSession); 

      completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, urlCredential); 




    } 
    else 
    { 
     completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge, nil); 
    } 
} 

struct IdentityAndTrust { 

    var identityRef:SecIdentityRef 
    var trust:SecTrustRef 
    var certArray:AnyObject 
} 

func extractIdentity(certData:NSData) -> IdentityAndTrust { 
    var identityAndTrust:IdentityAndTrust! 
    var securityError:OSStatus = errSecSuccess 

    let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")! 
    let PKCS12Data = NSData(contentsOfFile:path)! 
    let key : NSString = kSecImportExportPassphrase as NSString 
    let options : NSDictionary = [key : "xyz"] 
    //create variable for holding security information 
    //var privateKeyRef: SecKeyRef? = nil 

    var items : CFArray? 

    securityError = SecPKCS12Import(PKCS12Data, options, &items) 

    if securityError == errSecSuccess { 
     let certItems:CFArray = items as CFArray!; 
     let certItemsArray:Array = certItems as Array 
     let dict:AnyObject? = certItemsArray.first; 
     if let certEntry:Dictionary = dict as? Dictionary<String, AnyObject> { 

      // grab the identity 
      let identityPointer:AnyObject? = certEntry["identity"]; 
      let secIdentityRef:SecIdentityRef = identityPointer as! SecIdentityRef!; 
      print("\(identityPointer) :::: \(secIdentityRef)") 
      // grab the trust 
      let trustPointer:AnyObject? = certEntry["trust"]; 
      let trustRef:SecTrustRef = trustPointer as! SecTrustRef; 
      print("\(trustPointer) :::: \(trustRef)") 
      // grab the cert 
      let chainPointer:AnyObject? = certEntry["chain"]; 
      identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certArray: chainPointer!); 
     } 
    } 
    return identityAndTrust; 
} 

變化工作正常的代碼更改文件

 <?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
<plist version="1.0"> 
<dict> 
    <key>NSExceptionDomains</key> 
    <dict> 
     <key>amazonaws.com.cn</key> 
     <dict> 
      <key>NSIncludesSubdomains</key> 
      <true/> 
      <key>NSThirdPartyExceptionRequiresForwardSecrecy</key> 
      <false/> 
      <key>NSThirdPartyExceptionMinimumTLSVersion</key> 
      <string>TLSv1.0</string> 
     </dict> 
     <key>amazonaws.com</key> 
     <dict> 
      <key>NSIncludesSubdomains</key> 
      <true/> 
      <key>NSThirdPartyExceptionRequiresForwardSecrecy</key> 
      <false/> 
      <key>NSThirdPartyExceptionMinimumTLSVersion</key> 
      <string>TLSv1.0</string> 
     </dict> 
     <key>xyz.com</key> 
     <dict> 
      <key>NSExceptionAllowsInsecureHTTPLoads</key> 
      <true/> 
      <key>NSTemporaryExceptionMinimumTLSVersion</key> 
      <string>TLSv1.2</string> 
      <key>NSRequiresCertificateTransparency</key> 
      <false/> 
      <key>NSIncludesSubdomains</key> 
      <true/> 
     </dict> 
    </dict> 
    <key>NSAllowsArbitraryLoads</key> 
    <false/> 
</dict> 
</plist> 

希望這會有所幫助。

+0

你在哪裏包含上述代碼中的文件 – Labeo

+0

你必須在項目中添加「client.p12」和「example.com.cer」證書文件。 – Karlos

+0

該應用會自動使用它? – Labeo

相關問題