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.

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I have another question regarding keychain, can you help? stackoverflow.com/questions/34053049/…
in swift 4: "b".data(using: String.Encoding.utf8)
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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.