I've read the Apple export restrictions for app using encryption and I'm baffled.
Is it worth to do all the CCATS / SNAP-R procedure only for encrypting my gamesave data?
Using encryption will prevent my app to be sold in some region?
Can my app be rejected because of encryption?
Thanks!
In my opinion it is not worth using encryption. A simple checksum can do pretty much the same.
Instead of encrypting your savegames you could calculate a checksum to detect if someone tried to change the savegame.
I agree with #pre, skip the encryption part and use HMAC (on ios) to make sure that your saves were not altered. To protected the HMAC secrete I would generate it using any random generator and store it in the keychain.
Keychain entries are not backed up so it is hard to read them if your iphone is not jailbroken. You can try this wrapper around keychain: https://github.com/carlbrown/PDKeychainBindingsController
The registration process is not that difficult. Most of it is filling out company info (name,address, etc.). There is only one part that asks you about your encryption. The process takes about 3 days and a few back-and-fourths.
Apple has the checkbox in iTunesConnect to mark if you use encryption for anything other than sign-in credentials. It appears like they are just covering their butts. You submit a screenshot of your completed form and they sign off on it right away.
For an outline of the steps you need to take see:
https://www.chatmap.io/blog/iPhone-iTunes-ERN-Encryption.php
In short, it's not a great deal of work to register.
Related
I am developing app, which uses sqllite db. I want to provide security to DB. Is there any ways to provide security to SQLite DB so that no one can read it by hacking device or something else.
Should we provide any encrytion or apple provides their own security? Which are ways to provide app DB security?
Thanks
#Quentin's comment is right - as long as someone has physical acces to your device, it's only a matter of time until it's cracked. However, you can make that amount of time take so long that it's not worth it.
If you were to encrypt your database, the decryption key would also have to be stored on the device (assuming you want it to work offline). You could use the keychain to store this key - then they have to crack the iPhone's keychain before they can get access to your data.
The other alternative is to only let your app work while online - store the key on your server and have the user login and authenticate before you pass the key back to the app. This s a bit more work from you but will ensure that the key and the data are stored in different locations.
Finally (and most securely), you could store everything on your server - that way you control the data nd the key yourself and deice theft won't make the slightest bit of difference. however, if your data set is big this might make the ui of your app more complicated. And it won't work offline, obviously :)
Yesterday I posted this question about protecting files: Protecting the app sandbox
As mentioned, it appears that this is effective for protecting a file if the user has a passcode on the iPad. Naturally this raises the question of how to handle the encryption if the user does not. Now I have an idea, but am not sure if it's feasible or not.
Is there any way to override the encryption key to use a custom one? My gut instinct is no, but I figured there may be a way. (Btw, this is just an experiment for fun, I don't plan on submitting this to the app store...) My application has a login, and it would be very handy if this could be handled at the application level to accommodate users that do not have a lock.
However, I suppose it wouldn't be unreasonable to disable the saving feature if there is no device passcode... Any thoughts?
You can generate encryption key, based on login/password, this allowing user to open his files only if he know password. However, you'll need provide ability to restore data in some way if user will forget his password.
I'm storing some healthcare data on a mobile phone and I'd like to know what the best system of encryption is, to keep the data secure. It's basically a bunch of model objects, that I'm serializing and storing using NSKeyedArchiver / the equivalent on Blackberry (the name eludes me for now)
Any tips? I don't want to make up security protocols as I go along, but one of the other threads suggested the following approach.
Generate a public / private key pair
Store the public key
Encrypt the private key with a hash of the user's password.
Use the public key to encrypt the byte stream.
Decrypt the pvt key, keep it in memory, whenever the user logs in, and decrypt the stored data as needed.
Is there a more standard way of doing this?
Thanks,
Teja.
Edit: I appreciate it that you're trying to help me, but the things currently being discussed are business level discussions, on which I have no control of. So rephrasing my question, if you ignore that it's healthcare data, but some confidential data, say a password, how would you go about doing it?
There might be an easier way for secure data storage. With iOS 4.0 apple introduced system provided encryption of application documents. This means that the OS is responsible for doing all the encryption and decyryption in a fairly transparent way.
Applications that work with sensitive user data can now take advantage of the built-in encryption available on some devices to protect that data. When your application designates a particular file as protected, the system stores that file on-disk in an encrypted format. While the device is locked, the contents of the file are inaccessible to both your application and to any potential intruders. However, when the device is unlocked by the user, a decryption key is created to allow your application to access the file.
So only when your app is active, the files can be read back in unencrypted format. But the nice thing is that they are always encrypted on disk. So even if someone jailbreaks the device, or backs it up, the retrieved files are worthless.
This was probably introduced to conform to some specific data security standard that is required. I can't find that anywhere though.
For more info see the iOS 4.0 release notes.
http://en.wikipedia.org/wiki/HIPAA
Make sure you read and understand this!
edit: Sorry, didn't even bother to check to see where the OP is from, but even if they aren't from the USA there are still some good practices to follow in HIPAA.
HIPPA is a business practice and total system level privacy/security regulation. As such, an app can't comply by itself on random hardware for a random user. You need to determine how your app fits into a client health care provider's total regulatory compliance process before you can determine what algorithm might be found to comply with that process.
My best advice would be, don't store sensitive data in the user's mobile phone.
If that is not an option for you, then some kind of public/private key encryption, such as one you described, would be the next best option.
I have some information I'd like to store statically encrypted on an iPhone application. I'm new to iPhone development, some I'm not terribly familiar with CoreData and how it integrates with the views. I have the data as JSON, though I can easily put it into a SQLITE3 database or any other backing data format. I'll take whatever is easiest (a) to encrypt and (b) to integrate with the iPhone view layer.
The user will need to enter the password to decrypt the data each time the app is launched. The purpose of the encryption is to keep the data from being accessible if the user loses the phone.
For speed reasons, I would prefer to encrypt and decrypt the entire file at once rather than encrypting each individual field in each row of the database.
Note: this isn't the same idea as Question 929744, in which the purpose is to keep the user from messing with or seeing the data. The data should be perfectly transparent when in use.
Also note: I'm willing to use SQLCipher to store the data, but would prefer to use things that already exist on the iPhone/CoreData framework rather than go through the lengthy build/integration process involved.
You can encrypt individual properties in your Core Data model entities by making them transformable properties, then creating an NSValueTransformer subclass which will encrypt and decrypt the data for that property. While this is not the whole-database decryption that you're looking for, it will have a much lower memory footprint than decrypting an entire database into memory. Additionally, it will allow the decryption to be done lazily, rather than all up front, so your application will load much faster. Depending on the encryption used, I would even expect that the on-disk data accesses for loading each entity would be slower than the decryption process for the properties, so you won't see that much of a performance penalty when accessing the properties.
Transformable properties like this are very easy to use, because you read and write to them as normal, while the encryption / decryption goes on behind the scenes.
Do you need to encrypt?
Newer iPhones (3Gs, 4, iPad...) encrypt all data on the device. With a single, hashed, salted password on your app, no one can get to the data without a password. Data is sandboxed from all other apps.
Data Protection on iOS
"The purpose of the encryption is to keep the data from being accessible if the user loses the phone."
iOS has had Data Protection since iOS 4, and Core Data has supported this for a long time. Data protection is designed for exactly the kinds of scenarios you are interested in. By default, Core Data NSSQLiteStoreType files have NSFileProtectionCompleteUntilFirstUserAuthentication for applications built with the iOS 5 API or later. The WWDC 2012 session Protecting the User's Data goes into this topic in much more detail, and recommends using NSFileProtectionComplete. You can use this with Core Data by passing that value in the options dictionary used to open your Core Data NSSQLiteStoreType store.
Example:
NSDictionary *storeOptions = #{ NSPersistentStoreFileProtectionKey : NSFileProtectionComplete };
if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self storeURL] options:storeOptions error:&error]){
The broader topic of device security is covered in iOS Device Security
I am currently using https://github.com/project-imas/encrypted-core-data to encrypt my coredata store. It is a custom implementation of NSIncrementalStore basically is a community replacement for apple's own persistent store that has an encryption option. It is a drop-in solution that works. You can also take the sqlite file out and decrypt it with whatever passcode you choose in many different clients.
The implementation does not have 100% coverage and doesn't allow for some features such as subquery predicates. I am due to submit my first PR to the repo to hope change that soon ;-). I almost have it completley working with a very complex coredata app. It also has the added benefit of allowing you direct SQLite access without having to worry about apple's implementation changing on you since you have full access to the source.
I succeeded in adapting Apple's CustomAtomicStoreSubclass example code for use in a Mac desktop application, resulting in an encrypted NSBinaryStore-style persistent store written as a single file in the filesystem. My approach:
Copy the CustomAtomicStoreSubclass & CustomAtomicStoreSubclassCacheNode class source code into my project and rename them
Store the key and initial vector in the Keychain
Use the OpenSSL library bundled with Mac OS X
Encrypt NSKeyedArchiver output and write the ciphertext to disc (decryption is the reverse)
I intercepted backing store reads & writes in the readFile, metadataForPersistentStoreWithURL:error:, setMetadata:forPersistentStoreWithURL:error:, and save: methods in CustomAtomicStoreSubclass.
The Subclassing Notes for the iPhone's NSAtomicStore Class Reference looks similar to that of Mac OS X's. Perhaps this approach might also work with the iPhone.
I know this is an old question, but it's still quite relevant and I recently had to tackle the subject myself.
Transformable properties are a potential solution, but did not seem to work with NSPredicates, which is a big drawback. I did not pursue the CustomAtomicStoreSubclass approach, but am curious if others have had success with it.
My concerns were similar to those of the original poster, and I ultimately wound up doing the following:
Decrypt the store to a temp file
Load the decrypted store normally
Migrate the store to an in-memory store
Delete the unencrypted store
In my case, my store was read-only, but this could be expanded to write the store back out, encrypt it, and delete the unencrypted store once more. You can also always skip #3 if you have a large store and/or aren't concerned about having an unencrypted file sitting around while your app is running.
The Core Data file I was working with was ~1MB, and could be encrypted/decrypted very quickly.
How do I encrypt or decrypt data?
"The Certificate, Key, and Trust Services API provides functions for generating symmetric and asymmetric encryption keys, creating and verifying digital signatures, and encrypting keys and nonces. The CommonCrypto library is used for symmetric encryption, hashing, and HMAC operations. Refer to Certificate, Key, and Trust Services Reference and the CC_crypto(3cc) man pages for for more information."
You can use Trasformables, and I confirm, you cannot use them with predicates, but (and it's worse) you cannot even use
... = [self primitiveValueForKey:#"crypted_data"];
if You use predicates..
it works fine if You crypt you data using:
[self setPrimitiveValue:cryptedPsw forKey:#"crypted_data"];
to crypt data. (and for example on the simulator.... and move on the project bundle later..)
Encryption is encryption no matter what format your data is in, and you certainly don't need to worry about how anything "integrates with the views." All you have to do is decrypt it before you try to read anything meaningful.
Let's say I need to access a web service from an iPhone app. This web service requires clients to digitally sign HTTP requests in order to prove that the app "knows" a shared secret; a client key. The request signature is stored in a HTTP header and the request is simply sent over HTTP (not HTTPS).
This key must stay secret at all times yet needs to be used by the iPhone app.
So, how would you securely store this key given that you've always been told to never store anything sensitive on the client side?
The average user (99% of users) will happily just use the application. There will be somebody (an enemy?) who wants that secret client key so as to do the service or client key owner harm by way of impersonation. Such a person might jailbreak their phone, get access to the binary, run 'strings' or a hex editor and poke around. Thus, just storing the key in the source code is a terrible idea.
Another idea is storing the key in code not a string literal but in a NSMutableArray that's created from byte literals.
One can use the Keychain but since an iPhone app never has to supply a password to store things in the Keychain, I'm wary that someone with access to the app's sandbox can and will be able to simply look at or trivially decode items therein.
EDIT - so I read this about the Keychain: "In iPhone OS, an application always has access to its own keychain items and does not have access to any other application’s items. The system generates its own password for the keychain, and stores the key on the device in such a way that it is not accessible to any application."
So perhaps this is the best place to store the key.... If so, how do I ship with the key pre-entered into the app's keychain? Is that possible? Else, how could you add the key on first launch without the key being in the source code? Hmm..
EDIT - Filed bug report # 6584858 at http://bugreport.apple.com
Thanks.
The goal is, ultimately, restrict access of the web service to authorized users, right? Very easy if you control the web service (if you don't -- wrap it in a web service which you do control).
1) Create a public/private key pair. The private key goes on the web service server, which is put in a dungeon and guarded by a dragon. The public key goes on the phone. If someone is able to read the public key, this is not a problem.
2) Have each copy of the application generate a unique identifier. How you do this is up to you. For example, you could build it into the executable on download (is this possible for iPhone apps)? You could use the phone's GUID, assuming they have a way of calculating one. You could also redo this per session if you really wanted.
3) Use the public key to encrypt "My unique identifier is $FOO and I approved this message". Submit that with every request to the web service.
4) The web service decrypts each request, bouncing any which don't contain a valid identifier. You can do as much or as little work as you want here: keep a whitelist/blacklist, monitor usage on a per-identifier basis and investigate suspicious behavior, etc.
5) Since the unique identifier now never gets sent over the wire, the only way to compromise it is to have physical access to the phone. If they have physical access to the phone, you lose control of any data anywhere on the phone. Always. Can't be helped. That is why we built the system such that compromising one phone never compromises more than one account.
6) Build business processes to accommodate the need to a) remove access from a user who is abusing it and b) restore access to a user whose phone has been physically compromised (this is going to be very, very infrequent unless the user is the adversary).
The simple answer is that as things stand today it's just not possible to keep secrets on the iPhone. A jailbroken iPhone is just a general-purpose computer that fits in your hand. There's no trusted platform hardware that you can access. The user can spoof anything you can imagine using to uniquely identify a given device. The user can inject code into your process to do things like inspect the keychain. (Search for MobileSubstrate to see what I mean.) Sorry, you're screwed.
One ray of light in this situation is in app purchase receipts. If you sell an item in your app using in app purchase you get a receipt that's crypto signed and can be verified with Apple on demand. Even though you can't keep the receipt secret it can be traced (by Apple, not you) to a specific purchase, which might discourage pirates from sharing them. You can also throttle access to your server on a per-receipt basis to prevent your server resources from being drained by pirates.
UAObfuscatedString could be a solution to your problem. From the docs:
When you write code that has a string constant in it, this string is saved in the binary in clear text. A hacker could potentially discover exploits or change the string to affect your app's behavior. UAObfuscatedString only ever stores single characters in the binary, then combines them at runtime to produce your string. It is highly unlikely that these single letters will be discoverable in the binary as they will be interjected at random places in the compiled code. Thus, they appear to be randomized code to anyone trying to extract strings.
If you can bear to be iPhone OS 3.0-only, you may want to look at push notifications. I can't go into the specifics, but you can deliver a payload to Apple's servers along with the notification itself. When they accept the alert (or if your app is running), then some part of your code is called and the keychain item is stored. At this point, that is the only route to securely storing a secret on an iPhone that I can think of.
I had the same question and spent a lot of time poking around for an answer. The issue is a chicken and egg one: how to pre-poluate the keychain with data needed by your app.
In any case, I found a technique that at least will make it harder for a jailbreaker to uncover the information - they'll at least have to disassemble your code to find out what you did to mask the info:
String Obfuscation (if the link breaks search for "Obfuscate / Encrypt a String (NSString)")
Essentially the string is obfuscated before placed in the app, then you unobfuscate it using code.
Its better than doing nothing.
David
EDIT: I actually used this in an app. I put a base coding string into the info.plist, then did several operations on it in code - rot13, rotate/invert bytes, etc. The final processed string was used to decode the obfuscated string. Now, the three letter agencies could for sure break this - but at a huge cost of many hours decoding the binary.
I was going to say that this is the best technique I've come across, but I just read Kiran's post on UAObfuscatedString (different answer), which is a completely different way to obfuscate. It has the benefit of no strings saved anywhere in the app - each letter is turned into a method call. The selectors will show up as strings, so a hacker can quickly tell that your class used that technique though.
I think that this similar question, and my answer, may be relevant to your case too. In a nutshell, there was some talk of a trusted platform module being present in an iPhone. This would allow your service to trust an iPhone, even in the hands of an attacker. However, it looks like using the keychain is your best bet.
Did you consider/try the Push Notification suggestion, for initially transmitting the secret to the app & keychain? Or end up finding some other method to achieve this?
I'm going have my iphone app upload images to Amazon S3. Instead of putting the AWS credentials in the app, I am going to have the app phone home to my server for the URI and headers to use in the S3 upload request. My server will generate the S3 URI, proper signatures, etc. I can then implement a tighter, more specific security model on my app's webservice than AWS offers by itself and not give away my AWS keys to anyone with a jailbroken iphone.
But there still has to be some trust (credentials or otherwise) given to the app, and that trust can be stolen. All you can ever do is limit the damage done if someone jailbreaks an iphone and steals whatever credentials are in the app. The more powerful those credentials are, the worst things are. Ways to limit the power of credentials include:
avoid global credentials. make them per-user/application
avoid permanent credentials. make them temporary if possible
avoid global permissions. give them only the permissions they need. for instance, write permissions might be broken down into insert, overwrite, delete, write against resource group A or B, etc, and read could be broken into read named resources, read a list of all existing resources, read resource groups A or B, etc.
I would recommend creating a key at run time if possible. This way if the key were to get apprehended during a particular session, once the session ends, the key will be worthless. They could still apprehend the key from memory if they are smart enough, but it wouldn't matter since the key would become invalid after a period of time.
Sounds wonky. Would use HTTPS and maybe an encryption package to handle the key.
I think CommonCrypto is available for iPhone.
EDIT: Still sounds wonky. Why would anyone pass a secret key in an HTTP header? Anyone who traces your network traffic (via a logging wifi router, for instance) would see it.
There are well-established security methods for encrypting message traffic...why not use them rather than invent what is basically a trivially flawed system?
EDIT II: Ah, I see. I would go ahead and use the Keychain...I think it is intended for just these kinds of cases. I missed that you were generating the request using the key. Would still use HTTPS if I could though, since that way you don't risk people deducing your keygeneration scheme via inspection of enough signatures.