How does IOS Security work

how is security improved on ios 9 and how to remove ios security alert and how to close ios security alert and how to install norton security on ios
Dr.KiranArora Profile Pic
Published Date:27-10-2017
Your Website URL(Optional)
Security 8.0. Introduction Security is at the heart of iOS and OS X. You can use security functions in iOS to store data or files securely in different storage spaces. For instance, you can ask iOS to lock and secure your app’s data files stored on disk if the user has enabled a passcode for her device and her device is locked. If you do not explicitly ask for this, iOS will not use any secure storage for your app, and your app data will be available to be read by a process that has access to read your device’s filesystem. There are a variety of Mac applications out there that can explore an iOS device’s filesystem without the iOS device being jail‐ broken. Jailbreaking is the process of enabling root access and removing many protection layers built on top of an operating system, such as iOS. For instance, on a jailbroken device, an application can execute an un‐ signed binary. However, on a normal iOS device, for an app to be able to get executed on the device, it has to be signed either by Apple through the App Store, or through a verified iOS developer portal. Apple has had Keychain Access in OS X for a long time. Keychain Access is a program that allows OS X users to store data securely on their computers. Built on top of the Common Data Security Architecture, or CDSA, the Keychain Access and other security functionalities in OS X are available to programmers like us. Keychain Access can man‐ age various keychains. Every keychain itself can contain secure data such as passwords. For instance, on your OS X machine, when you log into a website using Safari, you will be prompted to either request for your password to be remembered by Safari or ignore that request. If you ask Safari to remember your password, Safari will then store the given password securely in your default keychain. The OS X and iOS keychains differ in various ways, as listed here: 367 htt a • In OS X, the user can have multiple keychains. In iOS, there is a single global key‐ chain. • In OS X, a keychain can be locked by the user. In iOS, the default keychain gets locked and unlocked as the device gets locked and unlocked. • OS X has the concept of a default keychain that gets automatically unlocked by OS X when the user logs in, as long as the default keychain has the same password as the user’s account password. iOS, as just mentioned, has only one keychain and this keychain, is unlocked by iOS by default. To get a better understanding of the keychain on OS X, before we dig deeper into the keychain and security concepts in iOS, I would like to demonstrate something to you. Open Terminal on your Mac, type the following command, and press Enter: security list-keychains The output, depending on your machine’s setup and your username, might be very similar to that shown here: "/Users/vandadnp/Library/Keychains/login.keychain" "/Library/Keychains/System.keychain" You can see that I have two keychains, the first being the login keychain and the second being the system keychain. To find out which keychain is the default keychain, type the following command in Terminal, and then press Enter: security default-keychain On a typical OS X installation, this command will return a result similar to this: "/Users/vandadnp/Library/Keychains/login.keychain" The output indicates that my default keychain is the login keychain. So by default, all passwords that I have asked various programs in my OS X installation to remember will get stored in the default keychain unless the app in question decides that it needs to store the password in a different keychain. The app will have to create that keychain if it’s not already there. Now let’s try something exciting. To find out what passwords are already stored in your default keychain, assuming that the default keychain as we found out earlier was the login.keychain, type the following command in Terminal and press Enter: security dump-keychain login.keychain grep "password" -i The dump-keychain argument to the security command in Terminal will dump the whole contents of a keychain to the standard output. We used the grep command to search for the passwords. The output of this command may be similar to the following, depending on your computer’s remembered passwords: 368 Chapter 8: Security htt asecurity dump-keychain login.keychain grep "password" -i "icmt"blob="Used to decode the encrypted file that contains non-password data previously entered in web page forms." 0x00000007 blob="iTunes iAd password" "desc"blob="iTunes iAd password" "desc"blob="iWork Document Password" OK, well, this is all great, but why am I talking about it, and how is it related to iOS? It turns out that the architecture of the keychain in iOS is very similar to OS X, because iOS was based on OS X’s source code. A lot of the concepts in iOS are similar to those in OS X, and the keychain is no exception. There are some really important things to note about the keychain in iOS, such as access groups and services. To ease you into the subject, I will demonstrate how they apply to OS X, and then I will talk more about the iOS implementation of the keychain. On your Mac, press Command+Space to open the Spotlight, or simply click the Spotlight icon on the top menu bar on your screen. When the Spotlight opens, type in “Keychain Access” and press the Enter key to open Keychain Access. On the lefthand side of Keychain Access, under the Keychains section, click the login keychain and then, under the Category section on the lefthand side, choose Passwords. Now you should see an interface similar to that shown in Figure 8-1. Figure 8-1. The Keychain Access on Mac OS X Keychain Access is the graphical user interface that sits on top of the keychain and security APIs in OS X, giving you a nice, clean interface that hides a lot of the complexity underneath the security frameworks in OS X. Now, if you have any passwords remem‐ 8.0. Introduction 369 htt a bered by apps such as Safari, double-click one of the password items on the righthand side of the Keychain Access screen to open a dialog similar to that shown in Figure 8-2. Figure 8-2. Keychain Access dialog displaying information for a saved password We need to know some of the properties of the password shown in Figure 8-2: Name The name of the password, which was assigned by the application that stored the item. For instance, this one is a WiFi password for a network named206-NET. This name is also sometimes referred to as the label. Kind The kind of item that this is. In this case, the kind is AirPort network password. This is a plain string and can be used to query the keychain later, as we will see. Account This is usually the key for the value that we want to store. The keychain uses a key- value store, just as dictionaries do in Objective-C. The key is an arbitrary string, and most applications that store items in the keychain store the key of the value in this section. Where Often referred to as the service, this is the identifier of the service that stored this item in the keychain. This identifier is something for you to remember, and the keychain doesn’t really care about it too much as long as it makes sense to you. In iOS, we usually set this service name to the bundle identifier of our apps to distin‐ guish our app’s stored values from other apps’ stored data. We will talk about this in a short while. 370 Chapter 8: Security htt a You can also see the Show password checkbox in Figure 8-2. Pressing this checkbox will ask for your permission to display the password for the item in question. If you enter your password and give permission to display the password for this item, Keychain Access will retrieve the secure password for you and display it on-screen. We can use the security command in Terminal to fetch the exact same information. If you type the following command in Terminal: security find-generic-password -help You will get an output similar to this: security find-generic-password -help Usage: find-generic-password -a account -s service options... -g keychain... -a Match "account" string -c Match "creator" (four-character code) -C Match "type" (four-character code) -D Match "kind" string -G Match "value" string (generic attribute) -j Match "comment" string -l Match "label" string -s Match "service" string -g Display the password for the item found -w Display only the password on stdout If no keychains are specified to search, the default search list is used. Find a generic password item. In iOS, even though the whole operating system has one global keychain area, an ap‐ plication can still just read from and write to a sandboxed area of the global keychain. Two apps written by the same developer (signed by a provision profile from the same iOS Developer Portal) can access a shared area of the keychain, but they still maintain their own sandboxed access to their own keychain. Therefore, two apps named App X and App Y, developed by the same iOS developer, can access the following keychain areas: 1. App X can access App X’s keychain area. 2. App Y can access App Y’s keychain area. 3. App X and App Y can both access a shared keychain area (using access groups, if the programmer configures the app’s entitlements appropriately). 4. App X cannot read App Y’s keychain data, and App Y cannot read App X’s keychain data. iOS looks at an app’s entitlements to figure out what type of access it requires. Entitle‐ ments of an app are encoded inside the provision profile that is used to sign the app. Assume you have just created a new provision profile called 8.0. Introduction 371 htt a provision and placed it on your desktop. Using the following command, you can extract the entitlements inside the profile, as follows: cd /Desktop That command will take you to your desktop, where you can issue the following com‐ mand to read the entitlements of your provision profile: security cms -D -i KeychainTest_Dev.mobileprovision grep -A12 "Entitlements" The security command shown here will decode the whole provi‐ sion profile, after which the grep command will look for the Entitle‐ ments section in the profile and read 12 lines of text at the begin‐ ning of it. If your entitlements contain more or less text, you might need to adjust the -A12 argument to read more lines or fewer. The output of that command will potentially look like this, depending on your profile: keyEntitlements/key dict keyapplication-identifier/key stringNSFileProtectionComplete/string stringF3FU372W5M/string keyget-task-allow/key true/ keykeychain-access-groups/key array stringF3FU372W5M./string /array /dict The important section that we are looking for is the keychain-access-groups section that specifies the access groups for our keychain items. This is the group identifier of the shared keychain for all apps developed by the same developer. In this case, the F3FU372W5M is my iOS portal’s team ID, and the asterisk after that shows what access groups in the keychain I can place my securely stored items in later. The asterisk in this case means any group, so by default, this app will be able to access the keychain items for any app that belongs to the aforementioned team. Don’t worry if this doesn’t make that much sense now. I can guarantee that by reading more about this subject in this chapter, you will get to know all a programmer needs to use keychain in iOS. It is absolutely crucial that you add the Security framework to your app before con‐ tinuing to read the recipes in this chapter. Most of the recipes in this chapter work with the keychain services in iOS, which require the presence of the Security framework. The iOS SDK 7 introduced the idea of modules, so that if you simply import the security 372 Chapter 8: Security htt afo framework’s umbrella header into your project, LLVM will link your application to the relevant security module; you won’t have to do the link manually. All you have to do is ensure that the Enable Modules feature is enabled in your build settings and that you import the following header file into your project: import Security Xcode 5 also added support for Capabilities, a new tab near the Build Settings tab. There, you can easily add entitlements to your app or even enable the keychain without much hassle. However, this hides almost every detail from you and doesn’t allow you to create your own provision profiles. All you will be able to use are Wildcard provision profiles, which is not what we usually use when adding push notifications and other capabilities to our apps. I suggest that you have a look at this new tab simply by clicking on your project file in Xcode, looking to the righthand side of the screen, and selecting Capa‐ bilities. You can then easily turn on or off features such as iCloud and Keychain Access. 8.1. Authenticating the User with Touch ID Problem You would like to harvest the power of Touch ID in your application to authenticate the user through his or her fingerprint. Solution Use theLocalAuthentication framework in your application. First, you need to create an instance of theLAContext class. This is just a handle to the Touch ID APIs you are going to use. When you have the handle to this object, invoke its canEvaluatePolicy:error: method to determine the availability of Touch ID for your application. Pass the value LAPolicyDeviceOwnerAuthenticationWithBiomet rics as the first parameter. You can also optionally pass a handle to an error object as the second parameter, so the method can notify you whether an error has occurred. The return value of the method is a Boolean indicating whether Touch ID is available on the device on which your code is running. Please bear in mind that Touch ID is currently not available for the simulator, so you will need a real device that supports Touch ID to test this recipe out for yourself. Assuming that Touch ID is available, you can now use theevaluatePolicy:localize dReason:reply: method of theLAContext local authentication context you created to authenticate the user using their Touch ID data. Note that the actual fingerprint infor‐ mation of the user is not exposed to any application. The only data you will receive from the local authentication framework is a true or a false value stating whether the user’s fingerprint was correct or not. That’s it 8.1. Authenticating the User with Touch ID 373 htt a As a setup for this recipe, I prepared a very simple user interface for an app that we can use in order to test the Touch ID functionality. Figure 8-3 shows what this app’s UI looks like. Figure 8-3. A simple Touch ID app UI I have also connected the two buttons to their corresponding outlets in our view con‐ troller: import UIKit class ViewController: UIViewController IBOutlet weak var buttonCheckTouchId: UIButton IBOutlet weak var buttonUseTouchId: UIButton The first button (which is also on the top of our view on our UI) will check the availability of touch UI when it is pressed. If Touch UI is available on the current device, pressing this button will enable the second button, which as you can see is disabled by default. Pressing the second button will then use the Touch ID APIs to authenticate the user. Here is our code for the first button: import UIKit import LocalAuthentication class ViewController: UIViewController IBOutlet weak var buttonCheckTouchId: UIButton IBOutlet weak var buttonUseTouchId: UIButton IBAction func checkTouchIdAvailability(sender: AnyObject) let context = LAContext() var error: NSError? let isTouchIdAvailable = context.canEvaluatePolicy( .DeviceOwnerAuthenticationWithBiometrics, error: &error) 374 Chapter 8: Security htt ao buttonUseTouchId.enabled = isTouchIdAvailable / Touch ID is not available / if isTouchIdAvailable == false let alertController = UIAlertController(title: "Touch ID", message: "Touch ID is not available", preferredStyle: .Alert) alertController.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil)) presentViewController(alertController, animated: true, completion: nil) IBAction func useTouchId(sender: AnyObject) / We will code this soon / This is very simple, isn’t it? We are just checking the availability of Touch ID and enabling or disabling the “Use Touch ID” button on our interface based on the availability of Touch ID. Now we have to work on actually using the Touch ID APIs. We will do so using theevaluatePolicy:localizedReason:reply: method ofLAContext. The pol‐ icy will be the same as we saw before. The localizedReason is the text that will be displayed to the user in a message when they are asked to provide their biometrics to be authenticated into your app. Here is your chance to let the user know why you need this authentication to take place. For instance, you can let the user know that they need to provide their biometrics data in order to access some sensitive information. IBAction func useTouchId(sender: AnyObject) / We will code this soon / let context = LAContext() var error: NSError? let reason = "Please authenticate with Touch ID " + "to access your private information" context.evaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reason, reply: (success: Bool, error: NSError) in if success / The user was successfully authenticated / else / The user could not be authenticated / 8.1. Authenticating the User with Touch ID 375 htt a ) Discussion Please be mindful when asking the user for authentication using Touch ID. The reason is that this is an inconvenience for the user, as it takes their attention away from the task at hand and focuses it on carefully placing their fingers on the Touch ID sensors. Also, not every iOS device is equipped with Touch ID sensors. So ensure that your app has another method of authentication for users on iOS devices that have no access to Touch ID sensors. Another thing to bear in mind is that the block object that you provide to the reply parameter of the evaluatePolicy:localizedReason:reply: method of LAContext may not be executed on the main thread or the thread that you call this method on. So if you do need to perform some work on the main thread, please ensure that you do so using the technique that you learned in Recipe 7.1. See Also Recipe 7.1 8.2. Enabling Security and Protection for Your Apps Problem You want to store values in the keychain and enable secure file storage for your app. Solution Create a provision profile for your app that has file protection enabled. Discussion Provision profiles, as discussed earlier in Recipe 8.0, “Introduction”, contain entitle‐ ments that dictate to iOS how your app utilizes the security functionalities in the oper‐ ating system. On iOS Simulator, apps do not get codesigned and, therefore, these con‐ cepts will not make sense. But for debugging your app on a device or submitting your app to the App Store, you need to ensure that your app is signed with the correct pro‐ vision profile for both the Debug and the Release schemes. I will show you the steps required to create a valid provision profile for your develop‐ ment, as well as Ad Hoc and the App Store. Follow these steps to create a valid devel‐ 376 Chapter 8: Security htt a opment provision profile (with debugging enabled) for the apps that we are going to be working on in this chapter of the book. We start by creating an App ID: I am assuming that you have already created valid development and distribution certificates for yourself. 1. Navigate to the iOS Dev Center and sign in with your username and password. 2. Find the iOS Developer Program section and choose Certificates, Identifiers & Profiles. 3. On the lefthand side of the screen, find and navigate to the App IDs section of the portal and press the plus button (+) to create a new App ID. 4. In the Name section, enter the name “Security App.” You can actually enter anything you want, but to avoid confusion in this chapter, it’s best to stick with the afore‐ mentioned name, which I will be using in examples. 5. Under the App Services section, check the Data Protection box and ensure that the Complete Protection option is selected. Leave the rest of the settings intact. 6. Under the App ID Suffix section, ensure that the Explicit App ID option is selected, and in the Bundle ID box, enter the dot-separated name of a service. I recommend com.NAME.REST, whereNAME is your company’s name. If you don’t have a company, make up a name I am using in examples, but you need a unique name, so you can’t use mine. 7. After you are done, press the Continue button. 8. You should now be asked to confirm your settings before your App ID is created, similar to the screen depicted in Figure 8-4. 8.2. Enabling Security and Protection for Your Apps 377 htt aFigure 8-4. Confirming your App ID settings before creating the App ID 9. When you are happy with your settings, press the Submit button to create your App ID. Beautiful Now we have an App ID, but we still need to create our provision profiles. I am going to walk you through creating your development provision profile, and I will let you create the Ad Hoc and your App Store profiles on your own because the process is almost identical. Follow these steps to create your development provision profile: 1. In the Certificates, Identifiers & Profiles section of the Developer Portal, choose the Development section of the Provisioning Profiles category and press the plus button (+). 2. In the screen that appears, under the Development section, choose the iOS App Development option and press the Continue button. 3. When asked to choose your App ID, select the App ID that you created earlier. For me, this would be the App ID shown in Figure 8-5. When you are happy with your selection, press the Continue button. 378 Chapter 8: Security htt aFigure 8-5. Choosing our new App ID for the new development provision profile 4. Choose the development certificate(s) to which you want to link your profile. Then press the Continue button. 5. Choose the list of devices on which your profile is allowed to be installed (only for Development and Ad Hoc profiles, not for App Store). Press the Continue button. 6. On the next screen, where you are asked to specify a name for your profile, enter something along the lines of “App Dev Profile” and then press the Generate button to create your provision profile. 7. Your profile is now ready to be downloaded (see Figure 8-6). Press the Download button to download your profile. 8.2. Enabling Security and Protection for Your Apps 379 htt aFigure 8-6. A development profile is generated and ready to be downloaded 8. To install the profile, drag and drop the downloaded profile into iTunes. This will install the profile with its original name into the /Library/MobileDevice/Provision ing Profiles/ folder. I have seen many iOS developers install a provision profile by double-clicking on it. While this does work in that it installs the profile into the aforementioned folder, it destroys the original profile’s filename and installs the profile using the SHA1 hash of the profile. If you later go into the aforementioned folder, you won’t be able to tell which profile is which unless you look inside the profiles for their names, so I strongly discourage this way of installing profiles. It’s best to either drag and drop the downloaded profiles into iTunes or manually paste the profiles into the aforementioned folder. Brilliant. You now have the provision profile installed on your computer. Use the build settings of your project to make sure that the correct profile is selected for the Debug scheme. After you follow the same process for creating your Ad Hoc and App Store profiles, you can ensure that your app is built with the correct Ad Hoc or App Store profile for the Release scheme. The provision profile that you created now will allow you to debug your apps on an iOS device and store data onto the disk or into the keychain with ease. See Also Recipe 8.0, “Introduction” 380 Chapter 8: Security htt a8.3. Storing Values in the Keychain Problem You want to securely store sensitive data in the keychain. Solution Ensure that your app is linked against the Security framework. Then use the SecI temAdd function to add a new item to your app’s keychain. Discussion Keychain APIs in both iOS and OS X are C APIs. That means we don’t have an Objective- C bridge or layer on top of the C APIs, so they are a bit more difficult to use than normal APIs. The key to learning the APIs is that the requests that we send to the keychain APIs are usually packed inside dictionaries. For instance, if you want to ask the keychain services to securely store a piece of data, you put your request—including the data that you want to store, the key for that data, the identifier of your app, etc.—inside a dictio‐ nary and submit that dictionary to an API such as theSecItemAdd function. To store a piece of value in the keychain, construct a dictionary with the following keys: kSecClass The value of this key is usually equal tokSecClassGenericPassword for storage of secure pieces of data, such as strings. kSecAttrService The value of this key is usually a string. This string usually is our app bundle iden‐ tifier. kSecAttrAccount The value of this key is a string that specifies the key to the value that we want to store. This is an arbitrary string that should make sense to you and your app. kSecValueData The value of this key is an instance ofNSData that you want to store for a given key (kSecAttrAccount.) The return value of the SecItemAdd function is of type OSStatus. The different values that you can receive from this function are defined inside the SecBase file in your SDK, so simply press the Command+Shift+O keys on your keyboard while in Xcode, type in SecBase, and try to find the valueerrSecSuccess. After you finderrSecSuccess in an enumeration, you will be able to see the rest of the values that can be returned inside a value of typeOSStatus. 8.3. Storing Values in the Keychain 381 htt a If the SecItemAdd function succeeds, you will receive the errSecSuccess value as the return value of this function. Otherwise, this function is indicating failure. So let’s put all this together and write a small piece of code that can write a string value to the keychain: import UIKit UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSObject : AnyObject?) - Bool let key = "Full Name" let value = "Steve Jobs" let valueData = value.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) let service = NSBundle.mainBundle().bundleIdentifier let secItem = kSecClass as NSString : kSecClassGenericPassword as NSString, kSecAttrService as NSString : service, kSecAttrAccount as NSString : key, kSecValueData as NSString : valueData, as NSDictionary var result: UnmanagedAnyObject? = nil let status = Int(SecItemAdd(secItem, &result)) switch status case Int(errSecSuccess): println("Successfully stored the value") case Int(errSecDuplicateItem): println("This item is already saved. Cannot duplicate it") default: println("An error occurred with code \(status)") return true If you run this app for the first time, assuming that you have followed the advice in previous sections of this chapter to set up your profile correctly, you will receive the 382 Chapter 8: Security htt a errSecSuccess value from theSecItemAdd function. However, if you run the same app again, you will receive theerrSecDuplicateItem value. This is Keychain’s way of telling you that you cannot overwrite the existing value. What you can do, though, is update the existing value, as we will see later in this chapter. See Also Recipe 8.2 8.4. Finding Values in the Keychain Problem You want to query the keychain to find an existing item. Solution Use theSecItemCopyMatching function. Follow these steps: 1. Construct a dictionary to pass to the aforementioned function. Add the kSec Class key to the dictionary. Set the key’s value to reflect the type of item that you are looking for. Usually the value should bekSecClassGenericPassword. 2. Add the kSecAttrService key to the dictionary. Set the key’s value to the service string of the item you are looking for. In this chapter, for service names, we use our app’s bundle identifier and we set the bundle identifiers of all our apps to the same string, so that one can write to the keychain, another can read the same data, etc. 3. Add the kSecAttrAccount key to the dictionary and set its value to the actual key of the value that you previously stored in the keychain. If you followed the example that we wrote in Recipe 8.3, the account name in this case would be the string “Full Name.” 4. Add the kSecReturnAttributes attribute to the dictionary and set its value to kCFBooleanTrue if you want to retrieve the attributes, such as the creation and modification date, of the existing value in the keychain. If you want to retrieve the actual value of the item you stored in the keychain, instead of the kSecReturnAt tributes key, add the kSecReturnData key to your dictionary and set its value to kCFBooleanTrue. When your dictionary is ready, you can pass it as the first parameter to the SecItemCo pyMatching function. The second parameter is a pointer to an object that will be re‐ turned by this function. This pointer must be of type CFTypeRef . This is a generic data type, and the type depends on what you pass as the first parameter to theSecItem CopyMatching function. For instance, if your dictionary contains the kSecReturnAt 8.4. Finding Values in the Keychain 383 htt a tributes key, the second parameter to this function must be eithernil or a pointer to a CFDictionaryRef opaque type. If you instead pass the kSecReturnData key to your dictionary, the second parameter to this function must be of typeCFDataRef, which is an opaque type that will receive the actual data of the existing item. You can then convert this data to an instance ofNSString and work with it. Discussion Suppose you want to read the properties of the string that you wrote to the keychain in Recipe 8.3. You can write your code in this way: import UIKit UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSObject : AnyObject?) - Bool let keyToSearchFor = "Full Name" let service = NSBundle.mainBundle().bundleIdentifier let query = kSecClass as NSString : kSecClassGenericPassword as NSString, kSecAttrService as NSString : service, kSecAttrAccount as NSString : keyToSearchFor, kSecReturnAttributes as NSString : kCFBooleanTrue, as NSDictionary var valueAttributes: UnmanagedAnyObject? = nil let results = Int(SecItemCopyMatching(query, &valueAttributes)) if results == Int(errSecSuccess) let attributes = valueAttributes.takeRetainedValue() as NSDictionary let key = attributeskSecAttrAccount as NSString as String let accessGroup = attributeskSecAttrAccessGroup as NSString as String let creationDate = attributeskSecAttrCreationDate as NSString as NSDate let modifiedDate = attributes kSecAttrModificationDate as NSString as NSDate 384 Chapter 8: Security htt afo let serviceValue = attributeskSecAttrService as NSString as String println("Key = \(key)") println("Access Group = \(accessGroup)") println("Creation Date = \(creationDate)") println("Modification Date = \(modifiedDate)") println("Service = \(serviceValue)") else println("Error happened with code: \(results)") return true When you run the app, results similar to the following print to the console: Key = Full Name Access Group = Creation Date = 2014-07-07 14:01:58 +0000 Modification Date = 2014-07-07 14:01:58 +0000 Service = That is great, but how can you now read the actual data of the value? The Solution section of this recipe already answered this: you have to include the kSecReturnData in your query. When you do that, the second parameter to theSecItemCopyMatching function will need to either benil or a pointer to aCFDataRef opaque variable, like so: func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSObject : AnyObject?) - Bool let keyToSearchFor = "Full Name" let service = NSBundle.mainBundle().bundleIdentifier let query = kSecClass as NSString : kSecClassGenericPassword as NSString, kSecAttrService as NSString : service, kSecAttrAccount as NSString : keyToSearchFor, kSecReturnData as NSString : kCFBooleanTrue, as NSDictionary var returnedData: UnmanagedAnyObject? = nil let results = Int(SecItemCopyMatching(query, &returnedData)) if results == Int(errSecSuccess) let data = returnedData.takeRetainedValue() as NSData 8.4. Finding Values in the Keychain 385 htt a let value = NSString(data: data, encoding: NSUTF8StringEncoding) println("Value = \(value)") else println("Error happened with code: \(results)") return true By default, theSecItemCopyMatching function looks for the first match in the keychain. Let’s say that you stored 10 secure items of class kSecClassGenericPassword in the keychain and you want to query them all. How can you do that? The answer is simple. Just add thekSecMatchLimit key into your query dictionary and provide the maximum number of matching items that the keychain services have to look for in the keychain or, alternatively, set the value of this key to kSecMatchLimitAll to find all matching items. When you include the kSecMatchLimit key in your query dictionary to the SecItemCopyMatching function, the second parameter to this method will then require a pointer to aCFArrayRef opaque type, and the items in this array will then be the items that you asked for. If you include thekSecReturnData key in your dictionary with the value of true, the items in this array will be of type CFDataRef. However, if instead of the kSecReturnData key, you included the kSecReturnAttributes key in your query dictionary with the value of true, the items in your array will be of type CFDictionar yRef and contain the dictionary object that describes the found item. See Also Recipe 8.3 8.5. Updating Existing Values in the Keychain Problem You have already stored a value in the keychain but now want to update it to a new value. Solution Given that you have been able to find the value in the keychain (see Recipe 8.4), you can issue theSecItemUpdate function with your query dictionary as its first parameter and a dictionary describing the change that you want to make to the existing value as its second parameter. Usually this update dictionary (the second parameter to the method) contains just one key (kSecValueData) and the value of this dictionary key is the data to set for the existing key in the keychain. 386 Chapter 8: Security htt ao

Advise: Why You Wasting Money in Costly SEO Tools, Use World's Best Free SEO Tool Ubersuggest.