A study of KeyChain under iOS

Source: Internet
Author: User

iOS Keychain is a relatively independent space, and when our program (APP) is replaced or deleted, the content saved in keychain is not deleted. Relative to Nsuserdefaults, plist file preservation and other general way, keychain save more secure. So we will use keychain to save some private information, such as passwords, certificates, device unique code (UDID) and so on.

We can think of keychain as a dictionary, all the data is stored in key-value form, you can do the add, update, GET, delete four operations on this dictionary.

The data structure is as follows:


For each application, keychain has two access areas, private and public areas. The private area is a sandbox, and any data stored by this program is not visible to other programs, and other applications cannot access the data in that area. If you want to put the stored content in a common area, to enable multiple applications to access some data together, you can first declare the name of the public area, the official document tube name is called "Keychain Access Group". The way to declare is to create a new plist file with a name that is random. As above: "YOUR_APP_ID_HERE.com.jaybin.keychain.test" is the name of this public access store.

Here we first introduce the access store of the KeyChain private area, that is, the private area can only be used for its own programs. such as saving user password, device unique code (UDID) and so on. To use keychain in the application, we need to import security.framework, Keychain's operation interface is declared in the header file SecItem.h. Using the SecItem.h method to manipulate the keychain, the code that needs to be written is more complex, and for ease of development, we can use some of the tool classes that have been packaged. Keychainitemwrapper is the Apple's official example "Generickeychain" in a keychain common operation of the package class, on the official website after downloading the Generickeychain project, only need to " KeychainItemWrapper.h "and" keychainitemwrapper.m "These two files are copied to the project and imported into the security.framework.

1, save the account information to keychain:


/* Initialize a Save user account Keychainitemwrapper */    keychainitemwrapper *wrapper = [[Keychainitemwrapper alloc] initwithidentifier:@ "UserAccount" accessgroup:nil];        Store user name, password    nsstring *username = @ "Jaybin" to keychain;    NSString *password = @ "123";    [Wrapper setobject:username Forkey: (ID) ksecattraccount];    [Wrapper Setobject:password Forkey: (ID) ksecvaluedata];

The identifier (Identifier) is used when we want to fetch data from the keychain later. If you want to share information between apps, you need to specify access groups (Keychain Access group). Applications with the same access group will be able to access the same keychain information. Here we first introduce the private area, so the accessgroup option is "nil". Note that the method "-(void) SetObject: (ID) inobject Forkey: (ID) key;" The value of the parameter "Forkey" should be security.framework inside the file "SecItem.h" Key, the key program will crash with other strings.

Through the above code operation, we have saved the user account information in the corresponding keychain of the application, even if the app is deleted, the account information in keychain will not be deleted.


2. Obtain the stored account information from keychain:

/* Initialize a keychainitemwrapper */    keychainitemwrapper *wrapper = [[Keychainitemwrapper alloc] initwithidentifier:@ " UserAccount "Accessgroup:nil";    Username = [Wrapper objectforkey: (ID) ksecattraccount];    Password = [wrapper objectforkey: (ID) ksecvaluedata];        NSLog (@ "name:%@", username);    NSLog (@ "password:%@", password);
Note that the identifier (useraccount) of the Keychainitemwrapper object must match the identifiers of the account information that we saved above. The Accessgroup option is also to fill in "nil". Of course the wrapper object corresponding to the key to correspond.

Here we still have a concrete look at the basic data structure of the keychain.

The entry in the keychain SecItem is called, but it is stored in CFDictionary . SecItemReftype does not exist. SecItemThere are five categories: universal password, Internet password, certificate, key, and identity. In most cases, all we use is a universal password. That is, 上面介绍的KeyChainItemWrapper only the universal password is used. Finally, we need to search for the required content in the keychain. There are many parts of the key that can be searched, but the best way is to assigned your identity to it and then search. Universal password entries contain attributes kSecAttrGeneric that can be used to store identifiers. This is also KeyChainItemWrapper the way of processing.


For example, the composition of each keychain, the whole is a dictionary structure.
The 1.kSecClass key defines the type of keychain (universal password, Internet password, certificate, key, and identity)
2. Different types contain different attributes, these attributes define the specific information of this item
3. Each item can contain a password entry to store the corresponding password

The general way of use is as follows:

/* Initialize a keychainitemwrapper */    keychainitemwrapper *wrapper = [[Keychainitemwrapper alloc] initwithidentifier:@ " UserAccount "Accessgroup:nil";    Set Keychain type to universal password    [wrapper Setobject:ksecclassgenericpassword Forkey: (ID) ksecclass];    Save user name    [wrapper setobject:@ "username" Forkey: (ID) ksecattraccount];    Save Password    [wrapper setobject:@ "Password" Forkey: (ID) ksecvaluedata];    Specify the access permissions for this data, which specifies that the application needs access to this data    [wrapper setobject: (ID) ksecattraccessiblealwaysthisdeviceonly Forkey: (ID) Ksecattraccessible];

Of course we want to know what information the iOS system and third-party apps store in keychain, and we can use keychain dumper. The most popular tool for exporting data from Keychain is the keychain dumper of Ptoomey3. Please refer to this blog post Http://blog.csdn.net/yiyaaixuexi for details.

Later we introduce keychain's public access store to enable different apps to share the data in keychain.

To implement some data that can be shared between multiple applications, you must first declare the name of the keychain public area, which is called "Keychain Access Group" in the official document keychain. The way to declare is to create a new plist file with a name that is random. For example, "YOUR_APP_ID_HERE.com.jaybin.keychain.test" is the name of this public access store. Here we can get a lot easier with the new version of Xcode.

Project->capebilities->keychain sharing, turn Keychain sharing on. Such as:



Keychain groups fills in the name "YOUR_APP_ID_HERE.com.jaybin.keychain.test" of this public access store. (Of course, the public access store name should be the same for multiple app settings that share keychain data.) We can see two "√" shown below, and if it is shown "x" You can click Fixit. This is because the path to this file is configured in Project->build Setting->code Signing entitlements, otherwise the public area is invalid. once configured, it must be compiled with your formal certificate signature before it can be passed. otherwise Xcode will frame the box to tell you that code signing has a problem. So, Apple restricts you to share keychain data with your company's products, and other companies won't be able to access your company's products keychain. In the new version of Xcode, when the keychain sharing is opened, the corresponding entitlements file (a plist file) is automatically generated in the corresponding directory of the project. Such as:



The path of this file is automatically configured in project->build setting->code Signing entitlements .


Here, we have basically completed the deployment of the Keychain public access store "Keychain Access group" settings. It is important to note that since the "Keychain Access group" is configured, it must be compiled with a formal certificate signature. So, Apple restricts you to share keychain data with your company's products, and other companies won't be able to access your company's products keychain. This means that applications of the same bundle can share keychain data of the same group with each other by setting group. The same bundle interpretation is: for example, there are two applications: the provision corresponding bundle ID used by a application is the bundle ID of the provision used by the COM.JAYBIN.KEYCHAIN1,B application. Com.jaybin.keychain2. Then the two applications can share keychain data. Here are examples of these two applications. (both programs must have keychain sharing turned on with the steps above, and the same "Keychain Access group" is set up)

Application A (bundle ID is com.jaybin.keychain1) Deposits account information to Keychain's public access store.

/* Initialize a Save user account Keychainitemwrapper */    keychainitemwrapper *wrapper = [[Keychainitemwrapper alloc] initwithidentifier:@ "UserAccount" accessgroup:nil];        Store user name, password    nsstring *username = @ "Jaybin" to keychain;    NSString *password = @ "123";    [Wrapper setobject:username Forkey: (ID) ksecattraccount];    [Wrapper Setobject:password Forkey: (ID) ksecvaluedata];

Application B (Bundle ID is com.jaybin.keychain2) reads the account information stored by application A from the public access store of keychain.

/* Initialize a keychainitemwrapper */    keychainitemwrapper *wrapper = [[Keychainitemwrapper alloc] initwithidentifier:@ " UserAccount "Accessgroup:nil";    Username = [Wrapper objectforkey: (ID) ksecattraccount];    Password = [wrapper objectforkey: (ID) ksecvaluedata];        NSLog (@ "name:%@", username);    NSLog (@ "password:%@", password);

It is important to note that a specific group was not specified when the Keychainitemwrapper object was created, since we have already opened the keychain sharing and set theEntitlements, the system will add the first group in your keychain-access-groups, which is the group ("YOUR_APP_ID_HERE.com.jaybin.keychain.test") that we have declared above.

A study of KeyChain under iOS

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.