1
votes

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.

3

3 Answers

1
votes

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.

1
votes

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.

-3
votes

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