11

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?

Raptor
  • 53,206
  • 45
  • 230
  • 366

1 Answers1

20

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];
  • 1
    clear answer. In-App decryption certainly will increase the loading of phone CPU usage, but I really want to safeguard our contents. Can you suggest a low-computation-power-needed way to encrypt & decrypt media contents? – Raptor Jun 02 '11 at 06:52
  • How about the *.strings files, I d'like to extract them, but seems the have encoding problems – MUH Mobile Inc. Aug 20 '12 at 19:56
  • 1
    @Muhaye I've updated my answer to include information about encrypting/decrypting `*.strings` files. –  Aug 21 '12 at 04:40
  • @darvids0n thx, but my problem is not the encryption rather (I think) than encoding trouble. You can see it your self by opening your Localization.strings locate in your *.ipa file – MUH Mobile Inc. Sep 13 '12 at 13:53
  • For the record, I came here because I'm running strings on my ipa file (enterprise deployment, not through the App Store), and I can't find my SuperSecretEncryptionKey. I'm thinking about building the string through code anyway, but I am curious why I can't find my key. – Millie Smith Jun 04 '14 at 22:36
  • I ran `strings` on a compiled-and-signed `.app` back in 2011 and found my decryption key. It's possible that Apple have since changed the signing process to obfuscate these strings. Regardless, it's still more secure to have a decryption key generated at runtime than to store a pregenerated one. –  May 13 '16 at 04:23