Just saw the Session 209 - Securing Application Data from de 2010 WWDC.
The keynote explains a lot of things, including the way you can set data protection attributes to your files (NSFileProtectionComplete, NSFileProtectionNone) and how to decide which protection is best for your case.
I just implemented it, but can't figure out how to test if the security is on, any ideas?
In addition, I have a sql lite database that needs to be accessed in background from time to time, and this method of data protection seems to be not good enough.. any link or tutorial that guide me through the best db protection? (found sql cipher but is kinda heavy to add in a evoluted project)
Thanks!
Testing can be done within Xcode:
NSFileProtectionComplete
You can use the iExplorer app to detect if your files are encrypted. iExplorer lets you browse the filesystem of your iPhone/iPad, and open the file (of course your device must be plugged into your Mac).
When the device is locked, the files can't be read correctly.
I don't think you can test Data Protection with computer-based tools and a non-jailbroken iPhone anymore - maybe you could in the past. Please see my answer here for an updated method for testing Data Protection: https://stackoverflow.com/a/40044841/1165843
From the NSFileManager class doc:
You just pass the constant when you set the file attributes.
http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StandardBehaviors/StandardBehaviors.html
EDIT (Determining the Availability of Protected Files)
A protected file is accessible only when a device is unlocked. Because applications may continue running while a device is locked, your code should be prepared to handle the possibility of protected files becoming unavailable at any time. The UIKit framework provides ways to track whether data protection is currently enabled.
Any application that works with protected files should implement the application delegate methods. When the applicationProtectedDataWillBecomeUnavailable: method is called, your application should immediately close any protected files and refrain from using them again until the applicationProtectedDataDidBecomeAvailable: method is called. Any attempts to access the protected files while they are unavailable will fail.
Verifying file protection on jailbroken devices
To step further, if you would like to test the file protection of exact file, then you would need a jailbroken device. For that, here are the (non-detailed) steps:
1) Jailbreak an iOS device
2) Install Open SSH via Cydia (This is required to remotely access files from that device) (https://cydia.saurik.com/openssh.html)
3) Login from your computer (using Mac client or Terminal) as a root user to your device.
To find location of your app's directories and files, there are various ways. Either you can
grep
the process of an app (Such asps ax | grep YourAppName
) - Make sure app is running on device to get the process details. It should give the location of app bundlesfind
you are interested in. For eg.find / -type f -name YouAppName.sqlite
. It should give file location on the device.From here, you can try to see if the file is really accessible or not, when phone is locked with a passcode; or not. - You can simply run
cat YouAppName.sqlite
to see if contents are accessible. Ia f file is protected, it should showerror; else if would show contents of file.
Again, this is required if you'd really like to check file protection of an individual file. If entitlements and capabilities are set properly, verifying entitlements should be enough for fileprotection.
On a side node, file explorer tools such as iExplorer don't help much in verification of FileProtection, because such tools require a device to be in "trusted" mode, so they have permissions to access the content of your device/apps.
Good luck!
Update: With iOS 6 it's supposedly possible to require data protection for your application by using an entitlement that needs to be configured on the App ID in the iOS provisioning profile. I haven't tested this yet, and this is the best information I could find on it https://devforums.apple.com/message/707939#707939
My investigations into this matter lead me to believe that it is very difficult to determine if data protection is enabled on a device.
File protection is enabled by setting the
NSFileProtectionKey
file attribute toNSFileProtectionComplete
For example, to create a protected file you could run code like:
Unfortunately this code will execute without error even if Data Protection is not enabled on the device (or if the code is run on the Simulator where Data Protection is not available).
Worse, the
NSFileProtectionComplete
attribute will be be set regardless of whether the file is protected or not. The following:will spit out
file protection value: NSFileProtectionComplete
no matter whether Data Protection is enabled or not.There are two methods that I've been able to use to discover if File Protection is working as expected. Unfortunately neither of these methods are suitable for detecting if Data Protection is enabled on a device in the field.
Both methods work on the idea that a protected file can not be read if the device is locked.
Method one involves using a timer to attempt to read the file after the device is locked, but while your application continues to run:
If you run the above code and lock a data protected device it will spit out:
The 20 second delay is necessary because there is a 10 second or so grace period where protected data is still available after a Data Protection enabled device is locked.
The second method is to create a protected file in an application, exit the application, lock the device, wait 10 seconds, and then use the XCode organizer to download the contents of the application. This will produce an error message and the protected file will be empty.
If either of the above tests fail to behave as described then Data Protection is either not enable, or your File Protection code was not implemented correctly.
Because I've not found any way to verify within the application that Data Protection is enabled before I write confidential information to disk, I've filed a feature enhancement request with Apple to be able to mark an application as requiring Data Protection to be enabled. (rdar://10167256)
Apple does offer a solution to this through their Mobile Device Management (MDM) APIs, which combined with a third party server can be used to enforce policies that require Data Protection to be enabled on devices.
File protection can be enabled on a per-file or per-directory basis, or can be enabled for the whole application (using entitlements and the provisioning profile). To determine if a file or directory is protected, check the filesystem attributes for the data protection key. This should be valid even it's a parent directory that was set to be protected:
To determine if the protected content is available, UIApplication provides a method for querying the protection state,
isProtectedDataAvailable
. Using it with the above method would allow you to determine wether a particular file or directory is available: