2

(I'm using Swift.)

I have the following Dictionary to pass to SecItemAdd().

var attributes = [kSecClass as String: kSecClassInternetPassword, kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly, kSecAttrDescription: "Alexander's Application Account Password", kSecAttrAccount: self.usernameField.text, /* This is an outlet to a UITextField */ kSecAttrServer: "http://www.hausofalexander.tk/", /* This is my servers' domain */ kSecAttrAuthenticationType: kSecAttrAuthenticationTypeHTTPBasic, kSecValueData: self.passwordField.text]; /* This is also and outlet to a UITextField */

Then I call SecItemAdd(attributes as CFDictionaryRef, nil)

I'm receiving errSecParam (which is error -50) because I'm passing an invalid parameter (attributes in this case) to SecItemAdd(). I'm assuming this is because I've a pair for kSecValueData in my attributes variable which isn't applicable to kSecClassInternetPassword for iOS according to the reference: Make sure you scroll down a bit to the kSecClassInternetPassword item to see the applicable attributes for a kSecClass of this type.

However, I'm completely able to use kSecValueData as an attribute and set a value for it with Cocoa (as in Mac development). I've made a Mac application to test this then looked for the item with Keychain Access to find that it was indeed there. However, this was using a kSecClass of kSecClassGenericPassword (I don't know if this is relevant, but this test application I'd written in Objective-C). At this point I'd decided to check which attributes are available if I were to use kSecClassGenericPassword in my iOS application. Sadly, kSecValueData isn't available for that kSecClass, either.

So where in the world do I set the password if kSecValueData isn't an applicable attribute to kSecClassGenericPassword, kSecClassInternetPassword, nor any other kSecClass items?

I've noticed that I'm allowed to use kSecAttrGeneric with these kSecClass items (namely kSecClassGenericPassword and kSecClassInternetPassword) and it takes a value of CFDataRef. I'm assuming that means I'm expected to pass NSData (as CFDataRef) to this attribute, but what do I pass as the NSData? Should that be a Dictionary? Should that be an NSASCIIStringEncoding value of the password String? Does this mean I can make any kSecAttr* value myself somehow?

Thanks for reading. If I've confused you, do tell and I'll happily explain in further detail.

IIllIIll
  • 504
  • 8
  • 25
  • maybe this will help - http://stackoverflow.com/questions/16922081/which-key-should-i-use-to-store-the-password-in-ios-keychain?rq=1 – Nitesh Jan 13 '15 at 22:46
  • I've been attempting to make this work for a bit, but `kSecValueData` simply isn't applicable. I've tried `var attributes = [kSecClass as String: kSecClassGenericPassword,kSecAttrAcces...blah blah...trAccount: self.usernameField.text,kSecValueData as String: self.passwordField.text.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)];`. After logging all of the Keychain items for the application I've found that `kSecValueData` is not being added as an attribute. Would it be bad practice to use `kSecGenericItem` instead? That's working well here. – IIllIIll Jan 14 '15 at 00:56
  • I have had issues getting these to work in the simulator but it ends up working on a device. Apple's example project helped me figure out the issues. https://developer.apple.com/documentation/localauthentication/accessing_keychain_items_with_face_id_or_touch_id – joels Jul 22 '20 at 20:00

0 Answers0