CFDictionaryCreate 在 Xcode 8 swift 3 中崩溃 [英] CFDictionaryCreate crashes in Xcode 8 swift 3

查看:92
本文介绍了CFDictionaryCreate 在 Xcode 8 swift 3 中崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下用于检索和存储 RSAkeydata 的代码

I have the following code for retrieving and storing RSAkeydata

fileprivate func retrieveAndStoreRSAKeyData(isPublic: Bool) throws -> CFData {

    var resultCode = noErr
    var result: CFData
    let value = {
        if isPublic {
            let t = self.publicTag
            print(t)
        }
        else
        {
            let s = self.privateTag
            print(s)
        }
    }
    var keyCallbacks = kCFTypeDictionaryKeyCallBacks
    var valueCallbacks = kCFTypeDictionaryValueCallBacks
    let keys = [Unmanaged.passUnretained(kSecClass).toOpaque(), Unmanaged.passUnretained(kSecAttrApplicationTag).toOpaque(), Unmanaged.passUnretained(kSecAttrKeyType).toOpaque(), Unmanaged.passUnretained(kSecReturnData).toOpaque()]
    let values = [Unmanaged.passUnretained(kSecClassKey).toOpaque(), Unmanaged<AnyObject>.passUnretained(value as AnyObject).toOpaque(), Unmanaged.passUnretained(kSecAttrKeyTypeRSA).toOpaque(), Unmanaged.passUnretained(kCFBooleanTrue).toOpaque()]
    let queryKey = CFDictionaryCreate(kCFAllocatorDefault,UnsafeMutablePointer.allocate(capacity: keys.count),UnsafeMutablePointer.allocate(capacity: values.count), 4, &keyCallbacks, &valueCallbacks)

    // Get the key.
    var item: AnyObject?
    resultCode = SecItemCopyMatching(queryKey!, &item)

    if(resultCode != noErr) {

        try generateKeyPair()
        /*
        Recurcively call the retrieval again after keys have been generated
        */
        result = try retrieveAndStoreRSAKeyData(isPublic: isPublic)
    }
    else {

        result = item as! CFData
    }

    return result
}

CFDictionaryCreate 总是失败并且代码在

The CFDictionaryCreate always fails and code crashes in this line in

     let queryKey = CFDictionaryCreate(kCFAllocatorDefault,UnsafeMutablePointer.allocate(capacity: keys.count),UnsafeMutablePointer.allocate(capacity: values.count), 4, &keyCallbacks, &valueCallbacks)

有人可以帮我解决这个问题吗?提前致谢

Can someone help me out on this. Thanks in advance

推荐答案

生成密钥对

func generateKeyPair(_ publicTag: String, privateTag: String, keySize: Int)->Bool {
        let privateAttributes = [String(kSecAttrIsPermanent): true,
                                 String(kSecAttrApplicationTag): privateTag] as [String : Any]
        let publicAttributes = [String(kSecAttrIsPermanent): true,
                                String(kSecAttrApplicationTag): publicTag] as [String : Any]

        let pairAttributes = [String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
                              String(kSecAttrKeySizeInBits): keySize,
                              String(kSecPublicKeyAttrs): publicAttributes,
                              String(kSecPrivateKeyAttrs): privateAttributes] as [String : Any]

        var publicRef: SecKey?
        var privateRef: SecKey?
        switch SecKeyGeneratePair(pairAttributes as CFDictionary, &publicRef, &privateRef) {
        case noErr: return true
        default: return false
        }
    }

和一些辅助函数

func obtainKey(_ tag: String) -> SecKey? {
    var keyRef: AnyObject?
    let query: Dictionary<String, AnyObject> = [
        String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
        String(kSecReturnRef): kCFBooleanTrue as CFBoolean,
        String(kSecClass): kSecClassKey as CFString,
        String(kSecAttrApplicationTag): tag as CFString,
        ]

    let status = SecItemCopyMatching(query as CFDictionary, &keyRef)

    switch status {
    case noErr:
        if let ref = keyRef {
            return (ref as! SecKey)
        }
    default:
        break
    }

    return nil
}

func obtainKeyData(_ tag: String) -> Data? {
    var keyRef: AnyObject?
    let query: Dictionary<String, AnyObject> = [
        String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
        String(kSecReturnData): kCFBooleanTrue as CFBoolean,
        String(kSecClass): kSecClassKey as CFString,
        String(kSecAttrApplicationTag): tag as CFString,
        ]

    let result: Data?

    switch SecItemCopyMatching(query as CFDictionary, &keyRef) {
    case noErr:
        result = keyRef as? Data
    default:
        result = nil
    }

    return result
}

func insertPublicKey(_ publicTag: String, data: Data) -> SecKey? {
    let query: Dictionary<String, AnyObject> = [
        String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
        String(kSecClass): kSecClassKey as CFString,
        String(kSecAttrApplicationTag): publicTag as CFString,
        String(kSecValueData): data as CFData,
        String(kSecReturnPersistentRef): true as CFBoolean]

    var persistentRef: AnyObject?
    let status = SecItemAdd(query as CFDictionary, &persistentRef)

    if status != noErr && status != errSecDuplicateItem {
        return nil
    }

    return obtainKey(publicTag)
}

func deleteKey(_ tag: String) -> Bool {
    let query: Dictionary<String, AnyObject> = [
        String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
        String(kSecClass): kSecClassKey as CFString,
        String(kSecAttrApplicationTag): tag as CFString]

    return SecItemDelete(query as CFDictionary) == noErr
}

func updateKey(_ tag: String, data: Data) -> Bool {
    let query: Dictionary<String, AnyObject> = [
        String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
        String(kSecClass): kSecClassKey as CFString,
        String(kSecAttrApplicationTag): tag as CFString]

    return SecItemUpdate(query as CFDictionary, [String(kSecValueData): data] as CFDictionary) == noErr
}

这篇关于CFDictionaryCreate 在 Xcode 8 swift 3 中崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆