Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

secItemAdd keep return -50 error in swift

Tags:

ios

keychain

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.

like image 360
user1470393 Avatar asked Dec 02 '15 19:12

user1470393


2 Answers

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.

like image 97
Tim Avatar answered Nov 15 '22 23:11

Tim


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)
like image 27
Maxim Makhun Avatar answered Nov 16 '22 00:11

Maxim Makhun