Encryption of contents in compiled iOS app ( IPA )

Raptor picture Raptor · Jun 2, 2011 · Viewed 10.7k times · Source

As IPA structure is just a zipped file containing compiled codes & media contents like images & audio, how can I protect the contents from being extracted and stolen by others? Is there any encryption I can add into the IPA?

Answer

user244343 picture user244343 · Jun 2, 2011

This answer mentions that the application is already encrypted by the time it gets onto your users' devices: Does Apple modify iOS application executables on apps submitted to the App Store?

Sorry, that's only the application binary. The other media are not encrypted, and no, there's no way to encrypt the .ipa. You could try encrypting your images and other media on your system, providing a bunch of application code to decrypt those resources when the app runs, and then your decryption code will become a part of the encrypted application binary. You can't submit an encrypted IPA though, it needs to be the file directly output from Xcode.

In response to your comment, the one I've used in the past is CommonCrypto. You can use this crypto library as a starting point.

Simple usage example of the above:

NSError *error;
NSMutableData *encryptedData = [NSMutableData dataWithContentsOfFile:pathToEncryptedFile];
NSData *decryptedData = [RNDecryptor decryptData:encryptedData
                                withPassword:@"SuperSecretDecryptionKey"
                                       error:&error];
UIImage *decryptedImage = [UIImage imageWithData:decryptedData];

IMPORTANT NOTE HERE: IF someone was to run the strings utility on your .app on a jailbroken iphone, or even on an iPhone they have filesystem access to via USB, they will get a list of all strings declared in your app. This includes "SuperSecretDecryptionKey". So you may want to use an integer, floating-point or other constant to do on-the-fly generation of a string decryption key, or make sure that the string you use to decrypt things is exactly the same as a normal system string so no-one suspects it as the true key. Security through obscurity, in this case, is advantageous.

To encrypt/decrypt *.strings files, you should encrypt the key and value strings in some manner (maybe one which gives you hexadecimal back, or any alphanumeric characters), and when you want to access a given value, say LicenceNumber, do this:

NSError *error;
NSData *unencryptedKey = [@"LicenceNumber"
                               dataUsingEncoding:NSUTF8StringEncoding];
NSData *encryptedKey = [RNEncryptor encryptData:unencryptedKey
                                withSettings:kRNCryptorAES256Settings
                                      password:@"SuperSecretEncryptionKey"
                                         error:&error]
NSData *encryptedValue = [[NSBundle mainBundle]
                                 localizedStringForKey:[NSString
                                  stringWithUTF8String:[encryptedKey bytes]]
                                 value:@"No licence"
                                 table:@"EncryptedStringsFile"];
NSData *decryptedValue = [RNDecryptor decryptData:encryptedValue
                                withPassword:@"SuperSecretDecryptionKey"
                                       error:&error];