secItemAdd keep return -50 error in swift
Asked Answered
E

2

14

Keep getting -50 when trying to add an item in security chain.

    var query = [String:AnyObject]()
    query[kSecClass as String] = kSecClassGenericPassword
    query[kSecAttrAccount as String] = "a"
    query[kSecValueData as String] = "b"
    let result = SecItemAdd(query as CFDictionary, nil);

result is -50. Can not figure out why, need help.. thanks in advance.

Eurythmics answered 2/12, 2015 at 19:37 Comment(0)
O
18

I believe the value for the kSecValueData key needs to be an NSData, not a String or NSString. Try encoding your string to data (with e.g. UTF-8 encoding). Untested snippet:

query[kSecValueData as String] = "b".dataUsingEncoding(NSUTF8StringEncoding)

For future reference, the error code -50 corresponds to errSecParam, which the SecBase.h header documents as meaning: "One or more parameters passed to a function were not valid." If you see this error again, try changing the values that you're passing in with your query dictionary.

Ocular answered 2/12, 2015 at 19:45 Comment(2)
I have another question regarding keychain, can you help? #34053549Eurythmics
in swift 4: "b".data(using: String.Encoding.utf8)Ova
L
7

Slightly updated Swift 5 version of add to/remove from keychain functionality:

@discardableResult
func addToKeychain(_ value: Data, tag: Data) -> Bool {
    let attributes: [String: Any] = [
        String(kSecClass): kSecClassKey,
        String(kSecAttrApplicationTag): tag,
        String(kSecValueData): value
    ]

    var result: CFTypeRef? = nil
    let status = SecItemAdd(attributes as CFDictionary, &result)
    if status == errSecSuccess {
        print("Successfully added to keychain.")
    } else {
        if let error: String = SecCopyErrorMessageString(status, nil) as String? {
            print(error)
        }

        return false
    }

    return true
}

@discardableResult
func removeFromKeychain(_ value: Data, tag: Data) -> Bool {
    let attributes: [String: Any] = [
        String(kSecClass): kSecClassKey,
        String(kSecAttrApplicationTag): tag,
        String(kSecValueData): value
    ]

    let status = SecItemDelete(attributes as CFDictionary)
    if status == errSecSuccess {
        print("Successfully removed from keychain.")
    } else {
        if let error: String = SecCopyErrorMessageString(status, nil) as String? {
            print(error)
        }

        return false
    }

    return true
}

Which can be used like this:

let value: Data = "key".data(using: .utf8)!
let tag: Data = "com.test.key".data(using: .utf8)!

removeFromKeychain(value, tag: tag)
addToKeychain(value, tag: tag)
Loxodromics answered 15/8, 2019 at 10:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.