OGeek|极客世界-中国程序员成长平台

标题: ios - 使用客户端证书和 secp512r1 的 TLS 1.2 连接失败 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-11 18:53
标题: ios - 使用客户端证书和 secp512r1 的 TLS 1.2 连接失败

我正在尝试实现双向 TLS 连接。这是流程:

在检查服务器和客户端之间的流量时,它似乎是客户端问题。

问题:

  1. iOS 9/10 是否支持 TLS 握手中的椭圆曲线键 secp512r1?
  2. 我错过了什么重要的事情吗?

任何想法,建议都非常感谢。谢谢。

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

//server trust works fine
if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
    if (self.shouldTrustProtectionSpace(space: challenge.protectionSpace)) {
        completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
    }
}
//This one causes the issue
else if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate) {
    let identityAndTrust: IdentityAndTrust = self.extractIdentity()

    let urlCredential: URLCredential = URLCredential(
        identity: identityAndTrust.identityRef,
        certificates: identityAndTrust.certArray as? [AnyObject],
        persistence: URLCredential.Persistence.forSession)
        completionHandler(.useCredential, urlCredential)
    }
}

struct IdentityAndTrust {
    var identityRef: SecIdentity
    var trust: SecTrust
    var certArray: AnyObject
}

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

    var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
    path = path + "/ca.p12"
    //let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")!
    let PKCS12Data = NSData(contentsOfFile:path)!
    let key: NSString = kSecImportExportPassphrase as NSString
    let options: NSDictionary = [key : "123"]
    //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: SecIdentity = identityPointer as! SecIdentity!
            print("\(identityPointer)  :::: \(secIdentityRef)")
            // grab the trust
            let trustPointer: AnyObject? = certEntry["trust"]
            let trustRef: SecTrust = trustPointer as! SecTrust
            print("\(trustPointer)  :::: \(trustRef)")

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

            let reader = DmailReader.sharedReader
            let caCertString = reader.getCACert()
            let cerData = X509Utility.der(fromData: caCertString)

            let convertedData = cerData as! CFData
            let caCert = SecCertificateCreateWithData(nil, convertedData)
            certArray.add(certRef as SecCertificate!)
            certArray.add(caCert!)

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



Best Answer-推荐答案


服务器似乎使用证书链响应了我的 csr 请求:一个客户端证书和一个中间证书。我只解析了第一个,显然跳过了中间。

 /*identity only contains client cert. Certificates is the array of intermediate certificates (in my case its 1, can be more)*/
 NSURLCredential *credential = [[NSURLCredential alloc]initWithIdentity:identity
                                                           certificates:certificates
                                                            persistence:NSURLCredentialPersistencePermanent];

然后传入 urlSession:didReceiveChallenge:completionHandler:

completionHandler(.useCredential, urlCredential)

关于ios - 使用客户端证书和 secp512r1 的 TLS 1.2 连接失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42141722/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (https://ogeek.cn/) Powered by Discuz! X3.4