Keychain Handling in iOS

 

What is Keychain

Keychain is Apple’s way to manage password in the the device. Whether its Mac or iOS Device they use the same Keychain system tool back inside. It stores all your passwords for applications, sensitive information relating to website’s credentials and credit card/ debit card numbers. The main objective of existence is to secure password & sensitive information of the device.

Keychain

Objective

Say, we have an app where you want to store username and password. Now, in such scenario, you will store these credentials (username and password) in NSUserDefaults.

Notably, it’s a great option to achieve the requirement but, it won’t give the utmost security to your password. As every app maintains a .plist file to save NSUserDefault value which can be extracted. And, it seems it’s not a reliable process to do so.

So, We will store the password in Keychain rather in NSUserDefault.

Prerequisite

  1. You need a Keychain Wrapper reusable files, which will handle your read-write operations.
  2. Then, You need a KeychainManager.swift which is app specific and handles all the read & write keychain request. Most of the time we use keychain manager to set & get the password.

Demonstration

Step1.

First, you import the Keychain Wrapper files in your Project.

Screen Shot 2017-03-06 at 4.50.16 PM

And, then import KeychainManager.swift which will behave as a middle layer between your View Controller(s) and KeychainWrapper Library.

Step2.

I’m assuming that, there is a requirement of storing password. So, we have a getter & setter methods belong to password.

  1. getPasswordFromKeychain()->String?
  2. setPasswordInKeychain(passedValue:)->Bool

First method is a getter method which returns String? (String Optional type) which suggest the method will either return String or nil.

Second method is a setter-method which accepts String type value as a parameter. It will return a BOOL status after completing the operation.

Step3.

On View Controller level, whenever you want to persist data into Keychain, you would call setter method (setPasswordInKeychain(passedValue:)) with the string parameter which you want to store.

if KeychainManager.setPasswordInKeychain(passedValue: "Hello@1234") == true{

  // After Success
}

If setPasswordInKeychain(passedValue:) acknowledge true or false. If it is true then, it has successfully inserted data into Keychain.

Now, it’s time to retrieve data from Keychain. So, we will call another method getPasswordFromKeychain()->String?

if let val = KeychainManager.getPasswordFromKeychain(){

               print("Saved Value is : \(val)")

}

 

Extra Features

  1. Say, you want to store some private into Keychain apart from password.

Approach :

Then, you need to modify Keychain Manager file according to your need.

private enum Keys:String{
       case Password = "kPassword"
   }

First, you need to add Key Name in your enum Keys.  Say, you want to add token then, it would look like

   private enum Keys:String{

       case Password = "kPassword"
       case Token = "kToken"
   }

Second, write a getter and Setter methods.

In both the methods, you just need to change the Key name and method’s name.

 

// Get Token
static func getTokenFromKeychain()->String?{

    return self.read(key: Keys.Token.rawValue) ?? nil
}   

//Set Token
static func setTokenInKeychain(passedValue:String)->Bool{

    return self.write(value: passedValue, key: Keys.Token.rawValue)
}
  1. Say, you have a logout feature and you want to clear Keychain data of your app.

Approach:

You need to call clearKeychainData() on logout button click.

  1. What if, User uninstall your app. And, then you want to delete the existing data from Keychain with it.

Approach:

In This case, you need to use NSUserDefault to check whether your app is launching for first time. If it is true then you should clear Keychain data.

 

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

       

       if(PersistenceManager.shared.getOpenForFirstTime(key: PersistenceKeys.isFirstTime)){

       

           //Clear Keychain Data

           let _ = KeychainManager.clearKeychainData()

           

           //Set To "False"

           PersistenceManager.shared.setOpenForFirstTime(value: false, key: PersistenceKeys.isFirstTime)

       }

       

       return true

   }

Note: Please refer to KeychainDemo for better understanding.

Conclusion

Whenever you want to save any piece of data into your keychain. You should add Keychain Wrapper files into your project. And then, modify Keychain Manager according to your requirement. And, that’s it.  You are good to go 🙂

Leave a Reply