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?
1 Answers
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];
-
1clear 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