marksmithhfx wrote:Further to this whole discussion hardware based encryption is now supported in the latest release of LC (5.5.2). See the iOS specific documentation for the command iphoneSetFileDataProtection filename, dataProtection. By setting the dataProtection attribute to "complete" the files will be encrypted (aes256 bit) when the device is locked, and unencrypted when the user enters their device pw.
For the technically inclined (I guess thats most of us) I ran across a new Apple document on iOS security here:
http://images.apple.com/ipad/business/d ... _May12.pdf
In this document it says: "When a file is opened, its metadata is decrypted with the file system key, revealing the wrapped per-file key and a notation on which class protects it. The per-file key is unwrapped with the class key, then supplied to the hardware AES engine, which decrypts the file as it is read from flash memory."
and later it says: "(NSFileProtectionComplete): The class key is protected with a key derived from the user passcode and the device UID. Shortly after the user locks a device (10 seconds, if the Require Password setting is Immediately), the decrypted class key is discarded, rendering all data in this class inaccessible until the user enters the passcode again."
So how does this play out in the real world? To find out I did a couple of tests.
Test #1: I have an sqlite file with iphoneSetFileDataProtection set to "complete".
Code: Select all
if the environment is "mobile" then
iphoneSetFileDataProtection t_db_path, "Complete"
end if
and later, just to be sure it is properly set I perform this test on the file when I open it
Code: Select all
if the environment is "mobile" then
put iphoneFileDataProtection(p_db_path) into field "protection" of card "home"
end if
which always returns "complete" as the result. Now, according to the above, 10 secs after I lock the device the class key should be thrown away and all data in the NSFileProtectionComplete class should be rendered inaccessible until the user re-enters the passcode.
HOWEVER, if I now back up the ipad using iTunes, and keep it turned off during the process, I get a readable file, not an encrypted one. Now, it is possible that Apple considers a backup by an authorized user THE SAME AS typing in the passcode. But that means they have kept a copy of the passcode hidden somewhere that they can call upon to un-encrypt the class key, and hence reveal the key for un-encrypting the data (this may be stored on my Mac and not on the iPad, I'm not sure). If I had to guess I would say that is what is going on ie. a legitimate backup is the same as typing in the user passcode.
Scenario #2: same as above, only this time I am going to copy the file off the iPad using Xcode, not iTunes. And the result this time is an
unreadable file (its actually a blank, empty file). So in this scenario Apple does not have access to, or make use of a copy of the passcode to decrypt the file. HOWEVER, as soon as I re-enter the passcode the file, when copied off by Xcode, is readable. Does that mean that Xcode is a legitimate user of the data and Apple decrypts the file when accessing it for download? Again, that is what I would guess.
So, what have we learned. #1 iphoneSetFileDataProtection complete appears to work to encrypt the file when it is not being accessed. It is likely that the file is adequately protected until an authorized user (either through iTunes, Xcode or the application itself) requests the file. However #2, we have also learned that it is very tricky to demonstrate this level of file protection. All we have been able to show with any certainty is that the file is encrypted when the device is locked and the passcode has been thrown away.
However, if even having it backed up to an iTunes backup in readable form makes you feel uncomfortable you have 4 options: (1) set the never backup flag to true or (2) put the file in a location that is not backed up by iTunes or (3) enable encrypted backups in iTunes or (4) encrypt the file yourself. Option 4 is particularly attractive if you want to subsequently move the file somewhere else and keep it encrypted while the file is being transferred. Options 1-3 don't support that. If you do go for option 4 you'll need to use a 3rd party encryption tool like Monte Goldings mergAES (which thankfully is compatible with LC's encrypt/decrypt routines allowing you to write a standalone utility to decrypt the file later). Also, if you want this encryption to take place not just when you quit your application, but also if the user turns off the device (or it times out), then you'll need to use another 3rd party external to detect that since LC does not currently detect a power down request. Again Monte comes to the rescue with mergNOTIFY and there may be other options as well.
If you go the route of encrypting the file yourself then the results of the above tests change as follows:
1. Backing up to iTunes: the file is encrypted
2. Copying from the device using Xcode, even when the passcode is entered: the file is encrypted.
In fact, by combining both forms of encryption you can be pretty confident the file is encrypted at all times except when your application requires access to it. And for those interested in doing there own encryption/decryption here are example routines:
Code: Select all
if there is a file p_pathname then
put URL ("binfile:" & p_pathname) into tData -- copy the sqlite file into a variable
-- check to see if the first word is 'SQLite'
set itemdelimiter to space
if item 1 of tData = "SQLite" then
put "something" into encryption_key
put mergAESOpenSSLEncrypt(tData,encryption_key) into temp
put temp into URL ("binfile:" & p_pathname) -- copy the encrytped file back over the orginal
end if
end if
and to decrypt the file:
Code: Select all
if there is a file p_pathname then
put URL ("binfile:" & p_pathname) into tData -- copy the encrypted file into a variable
-- check to see if the first word is 'Salted'
set the itemdelimiter to "d"
if item 1 of tData = "Salte" then
put "something" into encryption_key
put mergAESOpenSSLDecrypt(tData,encryption_key) into temp
put temp into URL ("binfile:" & p_pathname) -- copy the decrytped file back over the orginal
end if
end if