0

我正在尝试安装配置文件以使用 Swift 创建 VPN 连接。它创建了一个 VPN 连接,但我收到以下错误,我无法使用该 VPN 连接进行连接。

SecItemCopyMatching 失败:-50

钥匙串保存检索数据存在一些问题,但无法准确获取。

这是代码:

installVPNProfile(){

    let server: String? = "127.0.0.1"
    let username: String? = "MyServer"
    var _: String? = ""
    var _: String? = ""

    // Save password & psk
    //var password_Data = KeyChain.stringToNSDATA(string:"password")
    keychain.set(("12345").data(using: .utf8)!, forKey: "VPN_PASSWORD")        
    keychain.set(("12345abcde").data(using: .utf8)!, forKey: "PSK")

    vpnManager.loadFromPreferences(completionHandler: {(_ error: Error?) -> Void in
        if error != nil {
            print("Load config failed [\(String(describing: error?.localizedDescription))]")
            return
        }
        var p: NEVPNProtocolIPSec? = (vpnManager.protocolConfiguration as? NEVPNProtocolIPSec)
        if p != nil {
            // Protocol exists.
            // If you don't want to edit it, just return here.
        }
        else {
            // create a new one.
            p = NEVPNProtocolIPSec()
        }
        // config IPSec protocol
        p?.username = username
        p?.serverAddress = server
        p?.passwordReference = self.keychain.getData("VPN_PASSWORD")        // PSK
        p?.authenticationMethod = authentication type
        p?.sharedSecretReference = self.keychain.getData("PSK")
        p?.useExtendedAuthentication = true
        p?.disconnectOnSleep = false
        self.vpnManager.protocolConfiguration = p
        self.vpnManager.localizedDescription = "VPN Demo"
        self.vpnManager.isEnabled = true
        self.vpnManager.saveToPreferences(completionHandler: {(_ error: Error?) -> Void in
            if error != nil {
                print("Save config failed [\(error?.localizedDescription)]")
            }
        })
    })

}
4

1 回答 1

1

共享秘密引用和密码引用不应该是秘密数据本身,而应该是对数据的持久性引用。

当你设置 时passwordReference,你给它从getData函数返回的数据:

p?.passwordReference = self.keychain.getData("VPN_PASSWORD")

在设置sharedSecretReference. 我不知道您正在使用什么代码来包装钥匙串代码,但应该有一个函数返回引用,而不是数据本身。如果您的包装代码没有此功能,您应该使用支持此功能的 Keychain 库,或者自己创建它。

您可以在查询钥匙串时通过将kSecReturnPersistentRef密钥设置为true. 你从这个查询中得到的数据就是持久引用,而不是秘密。VPN 框架将在启动 VPN 连接时使用此引用从钥匙串中获取数据。

查看此示例如何为 VPN 配置文件创建和引用机密:http: //blog.moatazthenervous.com/create-a-key-chain-for-apples-vpn/

于 2017-08-08T12:21:39.753 回答