1

I need to store userLogin and userPassword in keychain for my app (containing app and extension that use keychain). Since I was searching a lot for some example how to do this I didn't find suitable example for my needs.

Almost every example treats userLogin as an keychain item attribute (which is not encrypted). I need to store credentials encrypted (userLogin + userPassword). How to store it without using kSecAttrAccount attribute. Do I need to store two items (one for login and one for password)?

I'm not using Keychain wrapper so answers in pure raw Keychain api would be great.

My general goal is to ask user one time about userName & userPassword authenticate it fetch authenticationToken if success and store it in keychain. During next app run I need to fetch this token from keychain but I don't have kSecAttrAccount anymore. I don't want to ask user again for userName to fetch authenticationToken. So I though that I can store both (userName & userPassword) in keychain encrypted or store only authenticationToken but then how to fetch it without account information.

Marcin Kapusta
  • 5,076
  • 3
  • 38
  • 55

3 Answers3

1

You can check my question Save data in Keychain only accessible with Touch ID in Swift 3 which seams unrelated, but actually you'll get detail code how to do what you want to do - it should help :)

The most important thing in that whole code is the following:

//  
//  This two valuse ideifieis the entry, together they become the
//  primary key in the Database
//
kSecAttrService: "app_name",
kSecAttrAccount: "first_name"

You set this values, so you know them as the developer :) This two values are the unique key that you would use normally in a SQL database. But since Apple likes to do thing differently then you have two values - because reason ;)

So when you update, delete or select, you have to pass this two values, that you set. For example:

kSecAttrService: "com.epic.app",
kSecAttrAccount: "login"

To save the user login

kSecAttrService: "com.epic.app",
kSecAttrAccount: "password"

To save user password.

Community
  • 1
  • 1
David Gatti
  • 3,576
  • 3
  • 33
  • 64
  • But during fetching encrypted data I need to provide `kSecAttrAccount` which my extension is not aware at all. I don't want to ask user for account and then fetch password for this account from keychain. – Marcin Kapusta Apr 10 '17 at 17:31
  • Updated my answer, check it out :) – David Gatti Apr 10 '17 at 18:23
  • Thanks. Now I now how to handle this. kSecAttrAccount can be some kind of id attribute that help me identify item in keychain. It doesn't need to be userName etc... at all. – Marcin Kapusta Apr 10 '17 at 18:40
  • Exactly :) and the super confusing Apple documentation strikes again :D – David Gatti Apr 10 '17 at 18:42
1

Just use a hard-coded account name, and store both the username and password in the data as a dictionary. The data of a keychain item can be anything you want, so use an NSKeyedArchiver to convert a dictionary to data, or convert it to JSON if that's more convenient. On iOS every app group has its own "virtual" keychain (i.e. different app groups won't interfere with each other, even though they're in the same physical keychain), so you don't have to worry about colliding with anyone. Just use whatever field values are convenient for you. Just because it's labeled "account" doesn't mean you have to put the username in there.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • 1
    Thanks for explanation. Yes I was thinking in wrong context because of the naming of this "account" attribute. So I think I'll store json in one keychain item and I'll put identifier of the item in kSecAttrGeneric so later It will be easy to fetch it, delete or update. – Marcin Kapusta Apr 10 '17 at 18:43
  • @MarcinKapusta can we save data in keychain on any ios device or there are some condition if user has logged in or not? – Er. Khatri Aug 11 '17 at 04:48
  • Hi, Do you know the difference between kSecAttrAccount and kSecAttrGeneric? I'm not sure how I should use the kSecAttrGeneric key. I wanna save different values in the app, not just passwords. – delarcomarta Sep 13 '19 at 10:19
  • Use `kSecClassGenericPassword` for storing arbitrary data. It says "password" but it just means "value." – Rob Napier Sep 13 '19 at 12:43
-3

Let's assume that a 'playground' service requires a password to be available in your shell's PLAYGROUND environment variable. Placing the password into your ~/.bashrc would accomplish this:

export PLAYGROUND="monkeybars"

Adding a secret to your keychain

To add a secret to your keychain, you can either use the graphical application ("Keychain Access") or the command-line utility security(1).

In the following example, we will create a password for an application called "playground":

Keychain Access

open /Applications/Utitlies/Keychain\ Access.app

chandan k.
  • 11
  • 1
  • 2