使用证书连接到VPN - iOS / Swift

时间:2017-10-31 09:59:41

标签: ios certificate vpn nevpnmanager

我正在建立一个需要证书进行身份验证的VPN连接。

以下代码是我如何设置VPN所需的配置。参数identityData是我将证书作为数据的地方。

func setupVPN(){
guard let vpnManager = NEVPNManager.shared() else { return }

vpnManager.loadFromPreferences { error in

    var hasProtocolConfig = false;

    if #available(iOS 9, *) {
        hasProtocolConfig = self.vpnManager.protocolConfiguration != nil
    } else {
        hasProtocolConfig = self.vpnManager.`protocol` != nil
    }

    if hasProtocolConfig == true {

        let p = NEVPNProtocolIKEv2()
        // All preferences here
        if let vpnData = self.vpnData {
        p.serverAddress = vpnData.getePDGAddress() // "X.X.X.X"
        p.localIdentifier = vpnData.getlocalIdentifier() // "XXXYYYZZWWWWWWWWWW@pppp.ppp.pppppp.pppppp.ppppppppppp.org"
        p.remoteIdentifier = vpnData.getAPN() // "gggggg.uuuuuuuuuuu"
        p.identityData = vpnData.getUserCertificateData() // User Certificate as Data
        }

        p.ikeSecurityAssociationParameters.integrityAlgorithm = NEVPNIKEv2IntegrityAlgorithm.SHA256
        p.ikeSecurityAssociationParameters.encryptionAlgorithm = NEVPNIKEv2EncryptionAlgorithm.algorithmAES128
        p.ikeSecurityAssociationParameters.diffieHellmanGroup = NEVPNIKEv2DiffieHellmanGroup.group14
        p.serverCertificateIssuerCommonName = "TEST SubCA"
        p.serverCertificateCommonName = "TEST SubCA"
        p.authenticationMethod = NEVPNIKEAuthenticationMethod.certificate

        if #available(iOS 9, *) {
            self.vpnManager.protocolConfiguration = p
        } else {
            self.vpnManager.`protocol` = p
        }
        self.vpnManager.isEnabled = true

        self.vpnManager.saveToPreferences { error in
            if let e = error{
                print("[VPN] error saving: " + e.localizedDescription)
            } else {
                print("[VPN] vpn saved")
                Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.connectVPN), userInfo: nil, repeats: false)
            }
            return
        }
    }
}

}

以base 64编码的证书的一个示例:

MIIFqTCCA5GgAwIBAgIQKLf5dlFRabt3cAe9ax2kXjANBgkqhkiG9w0BAQsFADBgMRwwGgYDVQQDDBNURVNUIFZGQ1ogRVBDIFN1Yk ... wdWJsaWMgYS5zLjELMAkGA1UEBhMCQ1owggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNgTmc6uQ9Md

然后解析数据就这样完成了:

CaCertificateData = Data(base64Encoded: "Base64StringEncoded_Here")

全部设置后,我以这样的方式启动VPN隧道:

do {
 try vpnManager.connection.startVPNTunnel()
} catch let error {
     print("Error starting VPN Connection \(error.localizedDescription)");
}

我可以看到VPN和VPN的状态开始连接然后变为断开连接。我们在上面看到的3算法是正确的。

有人可以注意到我做错了吗?我从一些不同的测试中得到了一些.pcap文件。在所有.pcap文件中,我不发送所需的消息“Client Hello”。我认为问题出在证书上。

1 个答案:

答案 0 :(得分:0)

您可以使用.ovpn文件。您可以轻松地将证书集成到ovpn文件中。 看看这篇文章https://medium.com/better-programming/how-to-build-an-openvpn-client-on-ios-c8f927c11e80