IOS请求与客户端证书身份验证

时间:2016-09-27 10:56:24

标签: ios objective-c swift ssl keychain

嗨,大家好我正在尝试应用此身份验证strategy。基本上我创建RSA密钥对,然后我创建CSR(证书签名请求),然后我发送到服务器,它将返回(X.509)自签名客户端证书作为响应。然后我删除---- BEGIN CERTIFICATE ----和---- END CERTIFICATE ----,将其转换为行长为64个字符的base64编码数据,并以这种方式将其保存到keychain

  1. 使用let certRef: CFTypeRef? = SecCertificateCreateWithData(nil , cert)
  2. 创建参考
  3. 使用let params: NSDictionary = [kSecClass as String: kSecClassCertificate, kSecValueRef as String: certRef!] let status = SecItemAdd(params, nil)
  4. 将其保存到钥匙串

    证书已保存,现在如果我理解正确,如果我在密钥链中保存了创建CSR的私钥,我应该能够获得我将在NSURLSession中使用的SecIdentity来发出请求。所以我创建了获取此身份的方法,这就是它的样子:

         func getIdentityReference() -> SecIdentityRef? {
            let parameters = [
                kSecClass as String: kSecClassIdentity,
                kSecAttrApplicationTag as String: kAsymmetricCryptoManagerApplicationTag,
                kSecReturnRef as String: true
            ]
            var ref: AnyObject?
            let status = SecItemCopyMatching(parameters, &ref)
            if status == errSecSuccess { return ref as! SecIdentityRef? } else { return nil }
        } 
    

    一切正常,我得到身份所以唯一要做的就是实际请求。为此,我需要实现NSURLSessionDelegate&s确实接受了挑战方法,这里是

    func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
            let method = challenge.protectionSpace.authenticationMethod
            print(method)
    
            if method == NSURLAuthenticationMethodServerTrust {
                let host = challenge.protectionSpace.host
                print(host)
    
                let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
                completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, credential)
            }
    
            let identity = AsymmetricCryptoManager.sharedInstance.getIdentityReference()!
    
            var certificate: SecCertificateRef? = nil
            SecIdentityCopyCertificate(identity, &certificate)
    
            var certArray = [certificate!]
            let credential = NSURLCredential(identity: identity, certificates: certArray, persistence: .Permanent)
    
            completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, credential)
        }
    

    (我只是原型设计,这是隐式解包的原因)

    但是当我发出此请求时,我收到了错误

    Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={_kCFStreamErrorCodeKey=-9824, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x13cfe7850 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9824, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9824}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://blabla.blabla, NSErrorFailingURLStringKey=https://blabla.blabla, _kCFStreamErrorDomainKey=3}
    

    现在我真的不知道问题出在哪里,请注意在Android上一切正常,所以服务器设置正确。任何帮助将不胜感激,它可能会帮助将来很少的人。 谢谢

0 个答案:

没有答案