我正在尝试安装配置文件以使用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)]")
}
})
})
}
答案 0 :(得分: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/