Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.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
Objective c 来自钥匙链的IKEv2密码引用_Objective C_Swift_Macos_Networkextension - Fatal编程技术网

Objective c 来自钥匙链的IKEv2密码引用

Objective c 来自钥匙链的IKEv2密码引用,objective-c,swift,macos,networkextension,Objective C,Swift,Macos,Networkextension,我正在尝试使用NetworkExtension框架在Mac OSX上实现IKEv2 vpn连接。每次我得到一个弹出窗口来输入我的vpn连接密码。根据NEVPN协议规范,可以通过提供存储在密钥链中的密码的持久引用来提供密码。但它不起作用。我曾在iOS中尝试过相同的IKEv2配置代码,效果非常好 我编写了一个示例应用程序来演示我是如何做到的- 密码在钥匙链中的存储方式: class func set(key: String, value: String) { let query: [NSO

我正在尝试使用NetworkExtension框架在Mac OSX上实现IKEv2 vpn连接。每次我得到一个弹出窗口来输入我的vpn连接密码。根据NEVPN协议规范,可以通过提供存储在密钥链中的密码的持久引用来提供密码。但它不起作用。我曾在iOS中尝试过相同的IKEv2配置代码,效果非常好

我编写了一个示例应用程序来演示我是如何做到的-

密码在钥匙链中的存储方式:

class func set(key: String, value: String) {

    let query: [NSObject: AnyObject] = [
        kSecValueData: value.dataUsingEncoding(NSUTF8StringEncoding)!,
        kSecClass: kSecClassGenericPassword,
        kSecAttrGeneric: key,
        kSecAttrAccount: key,
        kSecAttrAccessible: kSecAttrAccessibleAlways,
        kSecAttrService: NSBundle.mainBundle().bundleIdentifier!
    ]

    clear(key)
    SecItemAdd(query as CFDictionaryRef, nil)
}
class func persistentRef(key: String) -> NSData? {
    let query: [NSObject: AnyObject] = [
        kSecClass: kSecClassGenericPassword,
        kSecAttrGeneric: key,
        kSecAttrAccount: key,
        kSecAttrAccessible: kSecAttrAccessibleAlways,
        kSecMatchLimit: kSecMatchLimitOne,
        kSecAttrService: NSBundle.mainBundle().bundleIdentifier!,
        kSecReturnPersistentRef: kCFBooleanTrue
    ]

    var secItem: AnyObject?
    let result = SecItemCopyMatching(query, &secItem)
    if result != errSecSuccess {
        return nil
    }

    return secItem as? NSData
}
private func createIKEv2Protocol(host: String,
    username: String, password: String) -> NEVPNProtocolIKEv2 {

    Keychain.set(username, value: password)
    let passwordRef = Keychain.persistentRef(username)
    if passwordRef == nil {
        log("Failed to query password persistent ref")
    }

    let config = NEVPNProtocolIKEv2()

    config.remoteIdentifier = host
    config.serverAddress = host
    config.useExtendedAuthentication = true
    config.username = username
    config.passwordReference = passwordRef

    return config
}
如何从keychain检索持久引用:

class func set(key: String, value: String) {

    let query: [NSObject: AnyObject] = [
        kSecValueData: value.dataUsingEncoding(NSUTF8StringEncoding)!,
        kSecClass: kSecClassGenericPassword,
        kSecAttrGeneric: key,
        kSecAttrAccount: key,
        kSecAttrAccessible: kSecAttrAccessibleAlways,
        kSecAttrService: NSBundle.mainBundle().bundleIdentifier!
    ]

    clear(key)
    SecItemAdd(query as CFDictionaryRef, nil)
}
class func persistentRef(key: String) -> NSData? {
    let query: [NSObject: AnyObject] = [
        kSecClass: kSecClassGenericPassword,
        kSecAttrGeneric: key,
        kSecAttrAccount: key,
        kSecAttrAccessible: kSecAttrAccessibleAlways,
        kSecMatchLimit: kSecMatchLimitOne,
        kSecAttrService: NSBundle.mainBundle().bundleIdentifier!,
        kSecReturnPersistentRef: kCFBooleanTrue
    ]

    var secItem: AnyObject?
    let result = SecItemCopyMatching(query, &secItem)
    if result != errSecSuccess {
        return nil
    }

    return secItem as? NSData
}
private func createIKEv2Protocol(host: String,
    username: String, password: String) -> NEVPNProtocolIKEv2 {

    Keychain.set(username, value: password)
    let passwordRef = Keychain.persistentRef(username)
    if passwordRef == nil {
        log("Failed to query password persistent ref")
    }

    let config = NEVPNProtocolIKEv2()

    config.remoteIdentifier = host
    config.serverAddress = host
    config.useExtendedAuthentication = true
    config.username = username
    config.passwordReference = passwordRef

    return config
}
IKEv2配置:

class func set(key: String, value: String) {

    let query: [NSObject: AnyObject] = [
        kSecValueData: value.dataUsingEncoding(NSUTF8StringEncoding)!,
        kSecClass: kSecClassGenericPassword,
        kSecAttrGeneric: key,
        kSecAttrAccount: key,
        kSecAttrAccessible: kSecAttrAccessibleAlways,
        kSecAttrService: NSBundle.mainBundle().bundleIdentifier!
    ]

    clear(key)
    SecItemAdd(query as CFDictionaryRef, nil)
}
class func persistentRef(key: String) -> NSData? {
    let query: [NSObject: AnyObject] = [
        kSecClass: kSecClassGenericPassword,
        kSecAttrGeneric: key,
        kSecAttrAccount: key,
        kSecAttrAccessible: kSecAttrAccessibleAlways,
        kSecMatchLimit: kSecMatchLimitOne,
        kSecAttrService: NSBundle.mainBundle().bundleIdentifier!,
        kSecReturnPersistentRef: kCFBooleanTrue
    ]

    var secItem: AnyObject?
    let result = SecItemCopyMatching(query, &secItem)
    if result != errSecSuccess {
        return nil
    }

    return secItem as? NSData
}
private func createIKEv2Protocol(host: String,
    username: String, password: String) -> NEVPNProtocolIKEv2 {

    Keychain.set(username, value: password)
    let passwordRef = Keychain.persistentRef(username)
    if passwordRef == nil {
        log("Failed to query password persistent ref")
    }

    let config = NEVPNProtocolIKEv2()

    config.remoteIdentifier = host
    config.serverAddress = host
    config.useExtendedAuthentication = true
    config.username = username
    config.passwordReference = passwordRef

    return config
}

苹果开发者支持部回答了我的问题:


您的代码存在的问题是,它试图以不受支持的方式设置VPN。具体而言,IKEv2 VPN不支持基于密码的身份验证。您对IKEv2的选项列在NEVPNIKEAuthenticationMethod
enum中,即,.Certificate和.SharedSecret.`

Hi。您能提供一个工作代码示例吗?我也有同样的问题