【问题标题】:Swift websockets not accepting client certificateSwift websockets不接受客户端证书
【发布时间】:2017-10-19 09:49:54
【问题描述】:

我正在开发一个需要 websockets 客户端证书支持的项目。我目前正在使用 Starscream,但不幸的是,通过阅读文档,它似乎没有任何关于支持此功能的信息。我查看了其他几个 swift web socket 库,但没有一个提到对此的支持

有谁知道支持这种功能的库吗?

任何信息将不胜感激!

编辑:

所以我目前正在使用红蜘蛛来尝试这个。我已经设置了证书。这是我目前正在尝试的代码

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 Conn 0x604000173980 SSLHandshake failed (-9807) websocket is disconnected:操作无法完成。 (OS状态错误 -9807.)

我知道证书是有效的,因为我使用它来发出 https 请求并且它工作正常。那么有谁知道为什么它不起作用?或者有谁知道另一个可以帮助解决这个问题的套接字库?

【问题讨论】:

    标签: swift websocket


    【解决方案1】:

    您可以通过简单地使用 NSURLSession (URLSession) 来完成 SSL 固定,而无需使用任何第三方库,但如果您仍想使用其中之一,SocketRocket、AFNetworking 都支持它。

    以下链接应该对您有所帮助:

    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

    您选择的任何方法(第三方或 URLSession),我建议您阅读此安全问题:

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

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

    【讨论】:

    • 我的问题不在于 SSL pinning 和 web 请求,我使用 alamofire,我可以处理 SSL 问题没问题。我的问题纯粹是 websockets。我看过的套接字库没有提供处理这些身份验证问题的方法。SocketRocket 看起来很有可能,但它是一个旧库,并且是用 Objective-c 编写的。我希望有一个 Swift 解决方案
    猜你喜欢
    • 1970-01-01
    • 2010-09-15
    • 2018-05-12
    • 2021-10-03
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多