In my iOS4+ app i use AES encryption on several places and whole app has to be very secure. In order to do this I have to hard code several keys in this app which are then randomly picked when I need to encrypt something...
My question is how to store those private keys? Is it safe to hard-code them using NSString
? Or
#define SecretKeyString @"febd9a24d8b65c1c787d50a4ed3619a9"
If user jailbreaks iPhone with this app installed, couldn't he get those hard-coded keys? How can i hide them most effectively?
Thanks for any suggestion...
What others apps do is require the user to "log in" before they can use the app. Then you use their userid/password as a key to encrypt the keys or use a secured web service to get the keys for that user.
If you use a #define
or even an NSString, there are ways to guess the keys. Obviously, you have to truly be willing to spend a lot of time to find those keys in compiled code, but depending on the level of security you are looking for and the people you are guarding against, this might be a problem.
I recommend reading some articles on security by obfuscation, which is essentially what you are trying to achieve (at least thats what all the recommendations are saying) and are ultimately not secure.
However, iOS's sandboxing is your first and most effective form of security.
Second, input validation will be the next most important security feature your app will need. Having encryption all over means nothing if you don't validate all your input (from user typed info, to network responses to app launching via a scheme).
In the end, secure encryption, where it is necessary, is only secure if you do not hardcore (or obfuscate your hard coding). mprivat is correct, you'll need to use either user generated data (a login), a public key encryption (so only the non-included private key can decrypt) or a server side encryption that uses SSL for transport.
I'd also say that if your secure data is only to be maintained on the device that you use the keychain API, and in particular make sure that you use the form that requires the user to be logged in for item retrieval.
If you have data that you are encrypting on the device that is decrypted on both the device and on another device (like a server) you have a fundamental architectural flaw. It is quite important that encryption-decryption only ever be client-client (aka, user's device only) or client-server (which can be the users device to the server or the server to the users device). Mixing the two results in vulnerabilities. I'm specifically meaning the same encryption mechanism here, using a seperate encryption for client-client vs client-server is fine (and sometimes necessary).
Here's a must read for those who are needing to write secure code: http://www.amazon.com/gp/aw/d/0735617228