Encrypting iOS app binary file - ios

I'm building an iOS app but my app binary shows all my NSStrings that I've. Is there a way to encrypt it ?
I want to hide all my NSStrings from my app binary file.

You would not be able to encrypt your app binary in an secure way. You would at least need to pass the key next to the application bundle so the operating system would be able to encrypt the application before running it. And when you pass the key next to the application somebody interested in your application would be able to decrypt it too. So encrypting the whole binary file would be useless.
Do you ship passwords or API keys with your app bundle?
The best deal would be to redesign your application so such stuff isn't needed. You could try to prevent user from reading them directly out of your binary file, but they would always be able to get them. A couple of very smart guys have already tried that and failed, so don't waste your time trying to be better then them. So don't ship passwords or API keys!
If you still want to ship sensitive data in your binary:
You could give the following a try:
NSString *encryptedSensitiveString = #"mysensitivdatapreviosulyencpryted"; // <- this will be stored in your binary since it's a constant string
NSString *sensitiveString = [someHiddenKey decryptString:encryptedSensitiveString];
// Now you can use your sensitive string which is decrypted at runtime
If you are looking for some cryptography library for Objective-C you can use MIHCrypto framework based on OpenSSL.

As someone already stated, building or decrypting the strings dynamically is one choice.
Another is to use a 3rd party app protection system, like Arxan. I have never personally used it so can't really recommend it, but it does all sorts of obfuscation to prevent users from peeking into your app.

Related

Where to store some private data inside Swift Module, Cocoa Touch framework?

I need to store some private data (current session ticket or settings) inside my current Swift module. For the simple app the options usually are NSUserDefaults or some file on the disk so I don't need any app using my Cocoa Touch Framework to be able to access (at least modify) this data from outside, cause some app may clean it's own documents folder for some reasons and developer might simply not know about my data stored here. Same situation with NSUserDefaults.
Do modules have it's own documents folder?
I'm just wondering, what is the correct way to do that?
Any help would be great, thanks!
A Swift module defines a framework. Frameworks get their own bundle (which they can use for static assets that ship with the framework) but I believe that there is no API guidance or convention defining where they should persist data that the framework wants to hide from the app.
If you look at Apple's File System Programming Guide, it only has a section on defining "App-specific" locations for persisting data. The Framework Programming Guide doesn't seem to say anything about defining locations that are per-framework.
Given that, what I would do in my framework code is just use the app-specific storage location, but put all of my framework's data under a subdirectory or distinctive key string that clearly marked it with the name of the framework and was likely to be unique. So instead of saving to the Application Support/ directory, I'd save to Application Support/MyFramework/.
This will stop your framework from stomping on the hosting application's data. It won't stop a malicious hosting application from inspecting what your framework is saving, but that's a much harder problem to solve. Also, a clumsily-written hosting application could erase your data if it just erased all of its own data with a wildcard, but that might be its intent.
UPDATE:
As the commenter suggested, the keychain is also a reasonable place. But the keychain's security infrastructure does not (I believe) actually cryptographically protect you from the hosting app. Nonetheless it is a key value store that the hosting app is less likely to completely purge by accident.
If you really want to try to hide larger quantities of your framework's data from the hosting app then, alternatively, you could explore using URLForDirectory(_:inDomain:appropriateForURL:create:) to find a system-wide (rather than app-specific) temporary directory, and then hide your framework's data in there. But I think all of those directories are subject to deletion at will by the system, so it would only work if you were saving data that your framework could regenerate later, perhaps based on a smaller seed of data, stored in a place like the keychain.
The bottom line is if you're shipping a framework for other people to use, you cannot strongly hide anything from an application developer using the framework. They can attach a debugger. Then you lose. (If you want to go into the deep end on this, there's a whole area called "white box cryptography" that describes protecting data from an adversary that can completely observe your operations. This is the basis of modern DRM systems.)

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.

Encrypting data in iOS

I'm new to iOS development and working on a small iOS mobile app that stores sensitive information of users. Initially I thought of using custom AES encryption to encrypt/decrypt all the data. I also want the encrypted data to be synced with iCloud. After reading more I came to know from iPhone 3GS each device has a built-in AES-256 crypto engine. From the XCode, I observed that I can turn on an option called "Data Protection" for the mobile app to secure data. Based on my analysis I've below questions:
To use data protection for iPhone 3GS (uses iOS 6.1) do I need to set passcode?
Without setting passcode for the device how can I use the built-in crypto engine to encrypt my data?
The information are very sensitive and so in this case do I need to implement custom encryption?
RNCryptor is very useful, but it's basically just a wrapper for Apple's own CommonCrypto functionality (that makes implementing it pretty easy). It's useful if you want to encrypt data on the device that even the user cannot get ahold of.
Regarding your specific questions:
Data protection encrypts your app data using Apple's device-level encryption (you do not password protect it yourself). This has its uses - it will keep a 3rd party from being able to access data on a device if they are unable to unlock it - but does not prevent (for example) a user from getting access to data on their an unlocked device. Using RNCryptor and CommonCrypto which it is built upon you can AES256 encrypt content using a password of your choosing.
Apple details this here. Basically, from the end user's perspective they just set a password for their device as normal. You do not use a password of your own choosing.
You can set this up for your app using the following instructions:
https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/AddingCapabilities/AddingCapabilities.html#//apple_ref/doc/uid/TP40012582-CH26-SW30
This depends on how sensitive the data is and what threats you foresee (Who are you trying to keep it away from? Are there any laws/regulations you intend to comply with? How much work do you want to take upon yourself to protect this data?). There are a lot of trade-offs and caveats that can apply in certain situations.
If you have a small amount of data, you might consider just storing it in the iOS keychain. Otherwise, I'd recommend giving RNCryptor a try. It's fairly easy to integrate.
I hope this helps.
UPDATE: Another thing to consider... There are potential export control ramifications that might come up if you implement your own encryption, even using RNCryptor/CommonCrypto. Depending on how much paperwork and/or delay you're willing to deal with, this may influence your decision. You can learn more about this from Apple's site, here:
https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/wo/20.0.0.13.7.2.7.9.3.1.2.3.3.1.5.7.1
This really depends on how many scenarios you are trying to protect against. Pretty much any scenario you can possibly create will be broken given enough time and effort. However to address a few points:
1) Yes you need to set a passcode for this feature to become active.
2) You can make use of the CommonCrypto library (or a wrapper around it like RNCryptor)
3) This is a bad idea for the simple reason that developing a secure algorithm is insanely hard. The slightest flaw will leak out all of the data and people have devoted years of their lives to sniffing out these flaws (although I may have misunderstood what you meant by "custom encryption")
If you want to be as secure as possible you will have to do this: Send your file to a server for processing (via HTTPS). It is much harder to hack into a server then it is to hack into an iOS application. If you simply use RNCryptor it is pretty trivial to rip apart the app looking for the password, or how you obtain the password. Basically if the app can do it then BlackHat can do it too.
EDIT I forgot about one thing! If you generate a random password for each install and store it in the keychain then this will help, but it is not foolproof (There is a small chance that the iOS keychain contents can be retrieved from a jailbroken device, especially if the user has a week passcode). However this will make the user's data non-recoverable if they wipe the OS for any reason.
very very very simple : https://github.com/RNCryptor/RNCryptor
I was used it for a chat application it so good.

How to extract NSString value from executable

I'm encrypting data for an iPhone app using the CommonCrypto libraries. The data is local to the application. The encryption key is hardcoded in the code using an NSString.
I wonder if there is a way to access the value of this NSString from the app executable. I know that the code will be in executable form, but at the end an NSString have to store that value in plain text somewhere in the app. Accessing the app folder using iExplorer for example, will give full access to the executable.
Assuming the application was downloaded from the app store onto a device...
Decrypt the binary. This requires a jailbroken device, but it's trivial (there are many, many tools to do this, and tutorials on teh intarwebs)
Move the decrypted binary to a desktop
Run whatever tools you want on it. strings, etc. will all work. IDA Pro or Hopper will disassemble the binary and show not only the C strings in the binary, but the code that accesses it as well.
At this point you have the encryption key that ALL of the users of this application depend on.
...
Profit!
Pulling the C strings out of a binary is one of the first things any attacker will do. It's not recommended to store sensitive information in the binary, such as encryption keys. Unfortunately, there are not many secure ways to get an encryption key to a client. Assess the risks of different approaches and decide what level of exposure you are comfortable with.

Resources