views:

895

answers:

6

My client wants to encrypt/compress the html-code for their medical books in the iPhone bundle, to protect their IP.

Whats is a good way to prepare this file for the app bundle, and what complementary libraries (C, Obj-C) should I use to do the decryption and decompressing on the first launch of the app?

Copying the file to ~/Documents, then working on it seems like the best solution. Thoughts?

+1  A: 

I would keep the documents encrypted if I were you and just decrypt them as needed. One would easily be able to access the decrypted documents on a jailbroken device.

See the "Security Overview" document and the CryptoExercise sample code for encryption techniques

nduplessis
Right, that's of course a huge problem, and a good reason to only decrypt on the fly. I'm very worried about performance, though.
avocade
One more question: Would you guess the compression rate of the .zip packaging of the app bundle would be a lot worse if I have the encrypted file in the bundle than the regular html/ folder? If so, I'd need to do compression/decompression as a step on each load of a new html file as well.
avocade
Btw, the CrypotExercise code only seems to translate network data on the fly. I'm still not sure how to deal with the text-files (html code) I will load from the file system and translate in-flight, since the webview needs to load them at some points as files. Or strings...
avocade
+1  A: 

This is quite tricky... almost impossible to make it really unbreakable. Any reasonnably motivated person will be able to pierce through it. You'll only make it a little harder to do. In any case, you definitely can't store any secret key in the bundle itself. You'd need to securely obtain the decryption key over a secure channel from a server and use it as needed. Even then, someone doing jailbreak would probably be able to run GDB over your running program and extract the secret key in RAM + the secret key would be shared amongst all users of your app... You're essentially trying to implement a DRM scheme, which is inherently flawed by design... Unless you need offline access, you might want to pull the data as needed from a secure erver... at least you "could" throttle information leakage...

François P.
What I need right now is just the AES or whatever module to decrypting the html-files in-flight before sending loading by the UIWebView. I'll deal with the key storage problem later. One solution is to popup a UIAlertView on first launch to enter a short code, supplementing the key insde the app.
avocade
+1  A: 

Here's a few thoughts.

If the book text is all alphanumeric data, then don't save the data as ASCII - save them in your own binary encoded format (for instance use 5 bits instead of 8 and pack into words). That gives you a bit of compression, slight obfuscation and a very cheap (in clock cycles) decompression. You would have a data format that is quick to access on the fly and will keep the casual curious hacker out of the text. Clock cycles would be my main concern and security second.

Another idea is store the decrypt key for a typical Blowfish encryption in obfuscated format in the app. Split into two or three constants that require some odd operation to restore for instance. But of course, now the overhead of Blowfish or whatever will be your concern.

Since you will not be able to implement perfect security (perfection is extremely expensive), the IP owners will have to use traditional copyright and trade secret techniques to fully protect their property. You've made it harder to hack, but it's still up to the lawyers to be diligent, just a book on the shelf in the reserved section of the library (no photocopies please!).

Cheers

John Fricker
Right, I'm not after perfect security, as there is no such thing. I'd like to keep it as .html-files inside the full directory structure, with garbled text inside (images are a problem of course, but not of primary concern). Using a binary blob seems kludgy to me.
avocade
+1  A: 

You probably won't like it, but the best way is to just not use HTML. Once you pass the decrypted HTML to UIWebView, it is very easy for a malicious user to steal it at that level, defeating any purpose your encryption algorithm had. A UIView subclass with custom drawing code and a custom encrypted backing format will be much more difficult to work around

rpetrich
You're right, I don't like it :)The dictionary apps you can buy (e.g. WordBook) use some kind of binary blob to access the content (ends up as pure html passed to webview). It's a bit slow, but I guess it's mostly due to their heavy use of javascript.
avocade
Btw, how did you mean one could steal the code once it is displayed in the webview? Even if you can jailbreak the code, how would you get access to the raw data string that webview is using inside its own process?!
avocade
If you jailbreak the device you can use DYLD_INSERT_LIBRARIES to inject your own dylib into each process. Once loaded you can call +[UIWindow keyWindow], traverse the subviews looking for UIWebViews and send stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML;"
rpetrich
I currently use a less simple version of this technique for the UIWebView support in Clippy. It works reasonably well, but there is a lot of edge cases to look out for. It is doubtful that anyone would go that far just to get at your content (it would be cheaper to hire someone to retype it)
rpetrich
+1  A: 

From Mac OS X and iPhone OS Security Services:

You can use Keychain Services to encrypt and store small amounts of data (see Keychain Services Reference and Keychain Services Programming Guide). If you want to encrypt or decrypt larger amounts of data in Mac OS X, you can use the Common Security Services Manager (CSSM) Cryptographic Services Manager. This manager also has functions to create and verify digital signatures, generate cryptographic keys, and create cryptographic hashes. In iPhone OS, the Certificate, Key, and Trust Services API provides functions for generating encryption keys, creating and verifying digital signatures, and encrypting blocks of data; see Certificate, Key, and Trust Services Reference.

It's always a choice between performance (encryption just doesn't come free) and security (security and everything else, really). But what else is new? If you keep the individual files small enough, maybe decryption doesn't slow you down much. Alternatively, you may consider predictive decryption such that you have certain files being decrypted in the background, say those linked from the currently viewed file, etc. I realize, however, that concurrancy on the iPhone may be pretty spotty (I don't know as I haven't dropped the cash for a license). You may also realize performance gains by only encrytping those files that really need it; does an index/table of contents or other often accessed file really need to be encrypted? Does that count as IP your client is worried about?

+1  A: 

For compression I can recommend QuickLZ (fastest engine I saw, great compression ratio).

Bartosz Wójcik