Where to store decrypted files? - ios

I am encrypting downloaded files and saving them locally in app's documents directory.
To read them you must decrypt those file and store some where temporarily.
My concerns are:
1.if I store them in doc directory for time they are being used, for that time window one can get those files using tools like iExplorer.
2.My idea is to store them in memory for the time they are being used and flush the vault after use.
This option is good for small files but for large files say 50 MB or video of 100 MB, I am afraid that app will receive memory warning in result will terminate abruptly.
I want to know the best approach for doing this.

There is no perfect security storing local files in a safe way. If a person has full access to the device, he can always find a way to decrypt the files, as long as your application is able to decrypt it.
The only question is: How much effort is necessary to decrypt the files?
If your only concern is that a person may use iExplorer to copy and open these files, a simple local symmetric encryption will do the trick.
Just embed a random symmetric key in your application and encrypt the data block by block while you download it.
You can use the comfortable "Security Transforms" framework to do the symmetric encryption. There are some good examples in the Apple Documentation.
When you load the files, you can use the same key to decrypt them while you load them from the file system.
Just to make things clear: This is not a perfect protection of the files. But to decrypt the files, one has access to your app binary. Analyse this binary in a debugger and searching for the decryption part to extract your symmetric key. This is a lot effort necessary just to decrypt the files.

Split your files into smaller sizes before saving them, then decrypt on load.
Later edit: I noticed this is mentioned in the comments. I agree splitting files isn't the easiest thing in the world, but presumably you'll only need this for video. About 100MB is a lot of text or audio. If your PDF weights as much, it's probably scanned text, and you can change it into a series if images.
And yes, splitting better be done server-side, don't want the user waste battery in video processing.

Decrypt them, obfuscate them with a toy algorithm (e. g. XOR with a constant block), and store them in documents. When needed, load and decrypt.
Since the problem has no solution in theory (a determined enough attacker can read your process memory after all), it's as good a solution as any.

Related

iOS obfuscation of supporing files

I have an sqlite table and some audio in my iOS application that I have put a lot of work and effort into, but looking through iFile or any other browser based application I can easily find these files and do whatever I want with them. If I can do this then someone else and more malicious than myself would be able to do the same.
How can I obfuscate my files while keeping them usable?
What you need to do depends on who you are protecting them from.
Using NSData "Data Protection" will protect the file only wheb the iDevice is locked—at best but is a step up.
Another method is to encrypt them with a key which you save in the keychain. on an iPhone 6s can encrypt 1Mb in 6ms, an iPhone 4s in 30 ms (using Common Crypto), so there is really no noticible speed degradation. A good candidate for this is a 3rd party library: RNCryptor, it handes many details needed to do this right. The attacker will have to be more than a cyrious user, this may meet your needs.
You need to define the attacker you are protecting against ranging from a curious kid to a well funded government.
Depending on how hard you want to make it, just hash all filenames so people can't see them. if thats too easy encrypt them ... I have an answer here on SO that details how to do this

How do I secure data downloaded from a server on the user's device?

I am developing an App which will download some images from a server and save it on user's device. But what I am really concerned about is that these images should not be easily accessible by other apps or THE USER.
One approach could be that my App encrypts the images and saves them in the documents directory and decrypts them when required, but I think that it would make loading the images into UIImageView considerably slow.
There are many games which don't include large resources into their App-bundle to keep the App-size small and download the heavy resources later.
Where exactly do they save those resources?
And how do they secure them from being copied very easily from the directory where they are stored?
Probably because of trying to secure the files from the user the best option is to encrypt them with AES and saving them in the user area, Documents or Library directory or subdirectory thereof.
You are better off using Common Crypto. If RNCryptor suits you needs use it, it uses Common Crypto under the hood. Otherwise there is plenty of sample code for encrypting using Common Crypto here on SO.
Key the key should be random bytes as is the iv, save the key in the Keychain. Use AES in CBC mode with PKCS7 padding.
If you really want good security hire a cryptographic domain expert, the overall security is not trivial to get right. Don't forget the server and at a minimum use two factor authentication to it.
The decryption time should not be a problem, much faster that coming from a server.

How secure is a plist included in my xcode project after compilation?

If I store important values in a plist in xcode, is that less secure than if it was hard coded in a class? Could jail broken devices mess with those values easily? I know there's a certain level of risk with everything, but can someone explain the relative risks of a flat file vs hard coded values (in a MyClass.m file)?
Sub question:
How do you go about storing large amounts of initial data for a game/app to run on? It's fine if the values are readable, I just don't want them easily writable.
as for reading data:
plist data is not secure at all - getting plist content takes virtually no time! (and as the ipa is just a renamed zip you don't even need a device ;))
Extracting compiled code is 'harder' but in case of plain text strings only by a small margin.
(again: no need for a device)
as for writing to it:
data is you deliver is never writable without breaking the code signature. Therefore any method is fine. Often one ships CoreData databases when using CD, but I also use xmld, jsons, plists.. to deliver my content. whatever suits the needs best
note: breaking the code signature makes the app unusable on a stock iOS device but I think It'd remain usable on a jailbroken phone as the kernel doesn't really check the signature there
The values stored in you source files (.m) are safe, it is quite hard to access them. On the other hand accessing an app's plist, image sources, and other files are quite easy, there programs to achieve this (for example: Iexplorer) and it doesn't have to jailbroken at all.
So if you have sensitive information stored in your plist, it worth to encode the file, or store it in your source code.
Anyone can access a .plist file. But if is hard coded in a class is much more secure, use the second option. Nothing is 100% secure, but hard-coded in a class if someone want to access this value, the work is more hard.
You can store your Data into NSDictionary, then convert it to NSData, then do some simple crypto (re-order bytes for ex), then write to you application folder. When you want to read them, just take the content of the file, then decrypt, then re-create NSDictionary.
convert NSDictionary to NSData:
NSData *someDatas = [NSKeyedArchiver archivedDataWithRootObject:aDictionary];
convert NSData to NSDictionary:
NSDictionary *aDictionary = (NSDictionary*) [NSKeyedUnarchiver unarchiveObjectWithData:someDatas];
The data is secure in the way that the user cannot modify the content the right way cause the data won't be valid while application read it.
If you're looking to store sensitive values that you don't want jailbroken devices or reversed engineered app to get access to, you can easily think of using UAObfuscatedString.
As quoted:
When you write code that has a string constant in it, this string is saved in the binary in clear text. A hacker could potentially discover exploits or change the string to affect your app's behavior.
UAObfuscatedString only ever stores single characters in the binary, then combines them at runtime to produce your string. It is highly unlikely that these single letters will be discoverable in the binary as they will be interjected at random places in the compiled code. Thus, they appear to be randomized code to anyone trying to extract strings.
Having values hard coded in code or in a plist file is considered risky for sure.

iOS: Is there a way to delete specific files securely from the file system?

I am writing an application for iOS and a requirement I have been given is to remove files securely from the file system that may be given to my app from other applications (think 'Open in...'). These files are placed in a temp folder accessible to my app, but I'd like to securely delete these files once I have encrypted them in my own documents folder via the standard protection APIs. Any idea how to do that?
Quotes from the paper linked to by Bavarious:
We found that none of the available software techniques for sanitizing individual files were effective.
Overall, we conclude that the increased complexity of SSDs relative to hard drives requires that SSDs provide verifiable sanitization operations.
I'm not sure the flash memory in iPhones supports these operations, but if they do I'm pretty sure that Apple will have to make them available through their API and I haven't found anything in the API for this.
So basically it doesn't seem to be possible. Perhaps you could file a bug report with Apple and ask them to fix something like this.
I think you're better of looking into the possibility to encrypt the file before saving it.

How to "load" an encrypted (AES-256) PDF file in mmap() fashion using Quartz?

Yes, I know this question is kind of a mouthful of everything...
I have a PDF file on disk, which is encrypted (AES-256, using CommonCrypto/OpenSSL).
I'd like to render the PDF using Quartz' CGPDF... functions and found it's possible to create a CGPDFDocument with a CGDataProvider.
I'm wondering whether it's possible to create callbacks for the CGDataProvider, to decrypt and load only the blocks in memory that Quartz' PDF renderer needs. I'd rather not write the decrypted file to disk from a security/privacy perspective.
Any ideas?
Hopefully I can start an "enlighted" trial & error with the input of stackoverflow's community :)
If it's small enough, you can just keep it in an NSData - decrypt it on the fly and store it in memory. If it's larger, things are more difficult. Ultimately, people also can decrypt your binary and extract the AES key out of it.
PDF's password protection may add a small layer of security, but it's also very easy to circumvent.
What we did eventually is use the CGDataProviderCreateDirect API and implemented the C callbacks to decrypt parts of the encrypted PDF data, which was loaded using [NSData dataWithContentsOfMappedFile:] (which uses mmap() under the hood). This allowed us to render huge encrypted PDFs and having short loading times and low memory usage.

Resources