SecItemUpdate()不断返回errSecParam,我不知道为什么 [英] SecItemUpdate() keeps returning errSecParam and I can't figure out why

查看:112
本文介绍了SecItemUpdate()不断返回errSecParam,我不知道为什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是负责将值添加到加密存储中的整个功能.它在XCode 6的iPhone6模拟器上运行.

Here is the entire function responsible for adding the value into the encrypted store. This is running on the iPhone6 Simulator in XCode 6.

func addOrUpdateGenericPassword(password: String, withService service: String, andAccount account: String, withAccessibility accessibility: SecurityAccessibility) -> ReturnStatus
{
    var sacObject: SecAccessControlRef
    var accessFlag: CFStringRef = kSecAttrAccessibleWhenUnlocked

    switch accessibility
    {
    case SecurityAccessibility.AccessibleAfterFirstUnlock:
        accessFlag = kSecAttrAccessibleAfterFirstUnlock
    case SecurityAccessibility.AccessibleAfterFirstUnlockThisDeviceOnly:
        accessFlag = kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
    case SecurityAccessibility.AccessibleWhenUnlocked:
        accessFlag = kSecAttrAccessibleWhenUnlocked
    case SecurityAccessibility.AccessibleWhenUnlockedThisDeviceOnly:
        accessFlag = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
    }

    if touchIDEnabled
    {
        sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessFlag, .USerPresence, nil).takeRetainedValue()
    }
    else
    {
        sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessFlag, nil, nil).takeRetainedValue()
    }

    var dataFromString: NSData = password.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
    var secKeys: [AnyObject] = [kSecClass, kSecAttrService, kSecAttrAccount, kSecValueData, kSecAttrAccessControl]
    var secValues: [AnyObject] = [kSecClassGenericPassword, service, account, dataFromString, sacObject]
    var update = NSDictionary(objects: secValues, forKeys: secKeys)

    // attempt to get the value first to determine if it exists
    let (currentValue, rStatus) = getGenericPasswordWith(service, andAccount: account)
    if rStatus == ReturnStatus.errSecSuccess
    {
        // Item already exists, so do an Update
        // We need to build a query for the existing value here instead of using the one we built for updating
        var query = buildQueryValueForLookupWith(service, andAccount: account)
        var status = SecItemUpdate(query, update)
        return getReturnStatusCodeForOSStatusCode(status)
    }
    else if rStatus == ReturnStatus.errSecItemNotFound
    {
        // Item does not exist so add it
        var status = SecItemAdd(update, nil)
        return getReturnStatusCodeForOSStatusCode(status)
    }
    else
    {
        // some other error occured and we dont know what is going on!
        println("Unknown errr occured when checking if item already exists.  Status = \(returnStatusCodeToString(rStatus))")
        return ReturnStatus.errSecUnknownError
    }
}
func buildQueryValueForLookupWith(service: String, andAccount account: String) -> NSDictionary
{
    var secKeys: NSArray = [kSecClass, kSecAttrService, kSecAttrAccount, kSecReturnData]
    var secValues: [AnyObject] = [kSecClassGenericPassword, service, account, true]
    var query = NSDictionary(objects: secValues, forKeys: secKeys)

    return query
}

该代码在我编写的KeychainToolkit类中.这是出现错误时如何调用的示例:

That code is in the KeychainToolkit class I wrote. Here is an example of how I am calling it when I get the error:

var status = keychain.addOrUpdateGenericPassword(value!, withService: "healthBIT.lastSync", andAccount: key, withAccessibility: KeychainToolkit.SecurityAccessibility.AccessibleWhenUnlocked)

在这种情况下,值已经在钥匙串中,并且上面的代码正确地检测到该值,并使用SecItemUpdate()来更新其值.但是,无论我做什么,它总是返回errSecParam,并且我无法弄清楚我的参数哪里错了.

In this case the value is already in the keychain, and the above code properly detects that and uses SecItemUpdate() to just update its value. However it always returns errSecParam no matter what I do and I can't figure out where my params are wrong.

我也尝试过完全删除具有相同结果的新iOS8 kSecAttrAccessControl部分.

I have also tried it with completely removing the new iOS8 kSecAttrAccessControl part, with the same results.

推荐答案

我猜您不希望SecItemUpdate的查询字典中包含kSecReturnData.无法使用该API将数据返回给您.

I'm guessing you do not want kSecReturnData in the query dictionary for SecItemUpdate. There is no way to return the data to you with that API.

这篇关于SecItemUpdate()不断返回errSecParam,我不知道为什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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