Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 以编程方式连接到VPN会不断请求系统密钥链凭据_Swift_Macos_Certificate_Vpn_Nevpnmanager - Fatal编程技术网

Swift 以编程方式连接到VPN会不断请求系统密钥链凭据

Swift 以编程方式连接到VPN会不断请求系统密钥链凭据,swift,macos,certificate,vpn,nevpnmanager,Swift,Macos,Certificate,Vpn,Nevpnmanager,我的代码使用NEVPNManager和MacOS上的证书连接到VPN,代码运行良好,但每当我尝试连接targetManager.connection.startVPNTunnel时,系统会提示输入系统密钥链凭据 第一次批准后,是否有必要消除此警报 代码: }解决方法是不使用identityData和identityData Password,而是使用SecItemImport自己将标识导入用户的密钥链,然后通过identityReference属性将对标识的持久引用传递给NEVPNManager

我的代码使用NEVPNManager和MacOS上的证书连接到VPN,代码运行良好,但每当我尝试连接targetManager.connection.startVPNTunnel时,系统会提示输入系统密钥链凭据

第一次批准后,是否有必要消除此警报

代码:


}

解决方法是不使用identityData和identityData Password,而是使用SecItemImport自己将标识导入用户的密钥链,然后通过identityReference属性将对标识的持久引用传递给NEVPNManager。 以下是一个工作示例:

private func identityReference(for pkcs12Data: Data, password: String) -> Data {

    var importResult: CFArray? = nil
    let err = SecPKCS12Import(pkcs12Data as NSData, [
        kSecImportExportPassphrase: password
    ] as NSDictionary, &importResult)
    guard err == errSecSuccess else { fatalError() }
    let importArray = importResult! as! [[String:Any]]
    let identity = importArray[0][kSecImportItemIdentity as String]! as! SecIdentity

    var copyResult: CFTypeRef? = nil
    let err2 = SecItemCopyMatching([
        kSecValueRef: identity,
        kSecReturnPersistentRef: true
    ] as NSDictionary, &copyResult)
    guard err2 == errSecSuccess else { fatalError() }
    return copyResult! as! Data
}

func initVPNTunnelProviderManager(vpnConfig: Vpn, _ connect: Bool = false) {
let url = URL(string: vpnConfig.certUrl!)
do {
    let certData = try Data(contentsOf: url!)

    let targetManager: NEVPNManager = NEVPNManager.shared()
    targetManager.loadFromPreferences(completionHandler: { (error:Error?) in
        if let error = error {
            print(error)
        }

        switch targetManager.connection.status {
        case NEVPNStatus.connected:
            targetManager.connection.stopVPNTunnel()
            break
        case NEVPNStatus.disconnected:
            let ip = vpnConfig.serverUrl

            let providerProtocol = NEVPNProtocolIKEv2()
            providerProtocol.authenticationMethod = .certificate
            providerProtocol.serverAddress = ip
            providerProtocol.remoteIdentifier = ip
            providerProtocol.localIdentifier = "myIdentifier"

            providerProtocol.useExtendedAuthentication = false
            providerProtocol.ikeSecurityAssociationParameters.encryptionAlgorithm = .algorithmAES128GCM
            providerProtocol.ikeSecurityAssociationParameters.diffieHellmanGroup = .group19
            providerProtocol.ikeSecurityAssociationParameters.integrityAlgorithm = .SHA512
            providerProtocol.ikeSecurityAssociationParameters.lifetimeMinutes = 20

            providerProtocol.childSecurityAssociationParameters.encryptionAlgorithm = .algorithmAES128GCM
            providerProtocol.childSecurityAssociationParameters.diffieHellmanGroup = .group19
            providerProtocol.childSecurityAssociationParameters.integrityAlgorithm = .SHA512
            providerProtocol.childSecurityAssociationParameters.lifetimeMinutes = 20

            providerProtocol.deadPeerDetectionRate = .medium
            providerProtocol.disableRedirect = true
            providerProtocol.disableMOBIKE = false
            providerProtocol.enableRevocationCheck = false
            providerProtocol.enablePFS = true
            providerProtocol.useConfigurationAttributeInternalIPSubnet = false

            providerProtocol.serverCertificateCommonName = ip
            providerProtocol.serverCertificateIssuerCommonName = ip
            providerProtocol.disconnectOnSleep = true
            providerProtocol.identityReference = self.identityReference(for: certData, password: vpnConfig.certPassword!)
            providerProtocol.certificateType = .ECDSA256

            targetManager.protocolConfiguration = providerProtocol
            targetManager.localizedDescription = vpnConfig.name
            targetManager.isEnabled = true
            targetManager.isOnDemandEnabled = false


            targetManager.saveToPreferences(completionHandler: { (error:Error?) in
                if let error = error {
                    print(error)
                } else {
                    print("Save successfully")
                    if connect {
                        do {
                            try targetManager.connection.startVPNTunnel()
                        } catch {
                            print("Failed to connect")
                        }
                    }
                }
            })
            break
        default:
            print("connection status not handled: \(targetManager.connection.status.rawValue)")
        }
    })
} catch {
    print(error.localizedDescription)
}
}
private func identityReference(for pkcs12Data: Data, password: String) -> Data {

    var importResult: CFArray? = nil
    let err = SecPKCS12Import(pkcs12Data as NSData, [
        kSecImportExportPassphrase: password
    ] as NSDictionary, &importResult)
    guard err == errSecSuccess else { fatalError() }
    let importArray = importResult! as! [[String:Any]]
    let identity = importArray[0][kSecImportItemIdentity as String]! as! SecIdentity

    var copyResult: CFTypeRef? = nil
    let err2 = SecItemCopyMatching([
        kSecValueRef: identity,
        kSecReturnPersistentRef: true
    ] as NSDictionary, &copyResult)
    guard err2 == errSecSuccess else { fatalError() }
    return copyResult! as! Data
}

func initVPNTunnelProviderManager(vpnConfig: Vpn, _ connect: Bool = false) {
let url = URL(string: vpnConfig.certUrl!)
do {
    let certData = try Data(contentsOf: url!)

    let targetManager: NEVPNManager = NEVPNManager.shared()
    targetManager.loadFromPreferences(completionHandler: { (error:Error?) in
        if let error = error {
            print(error)
        }

        switch targetManager.connection.status {
        case NEVPNStatus.connected:
            targetManager.connection.stopVPNTunnel()
            break
        case NEVPNStatus.disconnected:
            let ip = vpnConfig.serverUrl

            let providerProtocol = NEVPNProtocolIKEv2()
            providerProtocol.authenticationMethod = .certificate
            providerProtocol.serverAddress = ip
            providerProtocol.remoteIdentifier = ip
            providerProtocol.localIdentifier = "myIdentifier"

            providerProtocol.useExtendedAuthentication = false
            providerProtocol.ikeSecurityAssociationParameters.encryptionAlgorithm = .algorithmAES128GCM
            providerProtocol.ikeSecurityAssociationParameters.diffieHellmanGroup = .group19
            providerProtocol.ikeSecurityAssociationParameters.integrityAlgorithm = .SHA512
            providerProtocol.ikeSecurityAssociationParameters.lifetimeMinutes = 20

            providerProtocol.childSecurityAssociationParameters.encryptionAlgorithm = .algorithmAES128GCM
            providerProtocol.childSecurityAssociationParameters.diffieHellmanGroup = .group19
            providerProtocol.childSecurityAssociationParameters.integrityAlgorithm = .SHA512
            providerProtocol.childSecurityAssociationParameters.lifetimeMinutes = 20

            providerProtocol.deadPeerDetectionRate = .medium
            providerProtocol.disableRedirect = true
            providerProtocol.disableMOBIKE = false
            providerProtocol.enableRevocationCheck = false
            providerProtocol.enablePFS = true
            providerProtocol.useConfigurationAttributeInternalIPSubnet = false

            providerProtocol.serverCertificateCommonName = ip
            providerProtocol.serverCertificateIssuerCommonName = ip
            providerProtocol.disconnectOnSleep = true
            providerProtocol.identityReference = self.identityReference(for: certData, password: vpnConfig.certPassword!)
            providerProtocol.certificateType = .ECDSA256

            targetManager.protocolConfiguration = providerProtocol
            targetManager.localizedDescription = vpnConfig.name
            targetManager.isEnabled = true
            targetManager.isOnDemandEnabled = false


            targetManager.saveToPreferences(completionHandler: { (error:Error?) in
                if let error = error {
                    print(error)
                } else {
                    print("Save successfully")
                    if connect {
                        do {
                            try targetManager.connection.startVPNTunnel()
                        } catch {
                            print("Failed to connect")
                        }
                    }
                }
            })
            break
        default:
            print("connection status not handled: \(targetManager.connection.status.rawValue)")
        }
    })
} catch {
    print(error.localizedDescription)
}
}