2017-10-19 118 views
4

我正在開發一個需要websocket客戶端證書支持的項目。我目前正在使用Starscream,但不幸的是,從閱讀文檔,它似乎沒有任何有關支持這方面的信息。我環顧了幾個其他的swift web socket庫,但是他們都沒有提到對此的支持Swift websockets不接受客戶端證書

有誰知道任何支持這種功能的庫嗎?

任何信息將不勝感激!

編輯:

所以我目前使用Starscream來試試這個。我有證書設置。這裏是我想到目前爲止

public struct IdentityAndTrust { 
    public var identityRef:SecIdentity 
    public var trust:SecTrust 
    public var certData : Data 
} 




var socket = WebSocket(url: URL(string: "\(ConstantKeys.ipAddress)")!, protocols: []) 
    var identityTest : IdentityAndTrust? 

func createTrust() 
{ 
    do 
    { 
     let urlPath  = Bundle.main.path(forResource: "client", ofType: "p12") 
     let url   = NSURL.fileURL(withPath: urlPath!) 
     let certificateData = try Data(contentsOf: url) 

     identityTest = extractTrustAndIdentity(certData: certificateData, certPassword: ConstantKeys.password) 
    } 
    catch 
    { 
     print(error) 
    } 
} 

func extractTrustAndIdentity(certData:Data, certPassword:String) -> IdentityAndTrust 
{ 
    var identityAndTrust:IdentityAndTrust! 
    var securityError:OSStatus = errSecSuccess 

    var items: CFArray? 
    let certOptions: Dictionary = [ kSecImportExportPassphrase as String : certPassword ]; 
    // import certificate to read its entries 
    securityError = SecPKCS12Import(certData as CFData, certOptions as CFDictionary, &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:SecIdentity = identityPointer as! SecIdentity!; 

      // grab the trust 
      let trustPointer:AnyObject? = certEntry["trust"]; 
      let trustRef:SecTrust = trustPointer as! SecTrust; 

      // grab the certificate chain 
      var certRef: SecCertificate? 
      SecIdentityCopyCertificate(secIdentityRef, &certRef); 
      let certArray:NSMutableArray = NSMutableArray(); 
      certArray.add(certRef as SecCertificate!); 

      identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certData : certData); 
     } 
    } 
    return identityAndTrust 
} 

我然後連接插座,像這樣

let key = SecTrustCopyPublicKey(identityTest!.trust)!; 
    let ssl = SSLCert(key: key) 

    socket.security = SSLSecurity(certs: [ssl], usePublicKeys: false) 
    socket.enabledSSLCipherSuites = [TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384] 
    socket.delegate = self 
    socket.connect() 

的代碼,但我得到了以下錯誤消息

CFNetwork的SSLHandshake失敗(-9807)

TCP連接0x604000173980 SSLHandshake失敗(-9807)websocket爲 斷開:操作公司沒有完成。 (OSStatus錯誤 -9807。)

我知道證書是有效的,因爲我使用它來發出https請求,它工作正常。那麼有人知道它爲什麼不起作用嗎?還是有人知道另一個套接字庫,可以幫助解決這個問題?

回答

0

您可以通過簡單地使用NSURLSession(URLSession)來完成SSL固定,而不使用任何第三方庫,但如果您仍然想使用它,SocketRocket,AFNetworking就可以支持它。

下面的鏈接可以幫助你:你選擇(第三方或URLSession)

http://www.yeradis.com/swift-authentication-challenge

http://www.indelible.org/ink/trusted-ssl-certificates/

https://jetforme.org/2013/05/validating-a-self-signed-ssl-certificate-in-ios-and-os-x-against-a-changing-host-name/enter link description here

的任何方法,我建議你閱讀本安全問題:

https://github.com/facebook/SocketRocket/pull/534

https://www.synopsys.com/blogs/software-security/ineffective-certificate-pinning-implementations/enter link description here

+0

我的問題是不是與SSL牽制和Web請求,我用alamofire,我可以處理SSL問題,沒有問題。我的問題純粹是用websockets。我所看到的套接字庫並不提供處理這些身份驗證問題的方法.SocketRocket看起來像是一種可能性,但它是一箇舊庫,並以Objective-c編寫。我希望有一個Swift解決方案 – AdamM