How to make a secure login using UDID or device token? - iphone

So I'm making an app where I want the users to be able add, edit and rate content, but I do not want to force them to register. Instead I was planning on just using their device id or device token to identify them. I'm planning on making both an iPhone and Android version, so I'm looking for a general solution, but the iPhone version has higher priority, so an iPhone specific solution would also be welcome.
The problem is that I don't want just anyone to be able to use my web service by sending a phony device id or someone else's device id.
How would the client prove to the server that it is providing the correct device id?

In theory, you cannot. A device ID is not particularly secret, and in most cases, it can be easily spoofed. As for Android, there's no reliable device ID on that OS at all - see the gory details here: Is there a unique Android device ID?
All you can rely upon is security by obscurity - hoping that no one will be determined enough to reverse-engineer the code and analyse the authentication protocol. And not disclosing the code is not an option - you are distributing the app after all.
That said, one not-particularly-secure auth method would be - send the device ID and a hash of device ID concatenated with a secret, hard-coded in the client code string (the shared secret). The service would contain a copy of the secret, recalculate the hash (using the device ID provided) and match the hashes. Not breakable by protocol analysis, only by digging in the code for the secret. Vulnerable to replay attacks though. Feel free to obfuscate the secret in the code - e. g. combine it together from parts stored in separate places right before use.
For a stronger solution, authenticate users, not devices. This is up to your customers, and depends on the nature of the business.

I am no Android expert but the IMEI code I think is unique for the device. I dont know though how you can read it and transmit it.

Related

iPhone DEV GUID question

I would like to know if it is possible, and if it's ok with apple if my app will use the iPhone's GUID with my server, as I don't want to nag my users for User/Passwords ...
Thanks !
Apple is crazy about privacy and UDID still allows to differentiate devices etc so I suggest to calculate some hash for example md5 and only afterward to pass it to the server. Such approach will guaranty privacy to your users even if your DB will be compromised.
Apple generally allows this and a lot of analytics frameworks use the device ID for tracking purposes.
You should however consider whether your users' data contains any personal information. If this is the case, I would strongly recommend against using device IDs for identification as they might not be really secret, e.g. because other developers need users' device IDs for beta testing etc. Also, other developers transmit device IDs to their servers and could use those to get at personal information from your users.
See this article for a concrete example of how device IDs could be abused.

Is it possible to have a single trial per device?

Is it possible to provide a service in which one free trial is given to each device without the possibility of an individual being able to get multiple free trials on a single device. If its impossible, do you know of a way of making it difficult to obtain multiple free trials.
You can generate the license key based on the device's unique ID, the request date, and your own private key to create a license that is only valid up to certain date.
You application will verify that the license key is valid by decoding the license key with your public key, and comparing its expiration date and device ID. People can't forge a bogus request, since the license key is only valid for the prescribed date and a given device ID.
(hint: read about public-key cryptography)
However, it's not totally foolproof. A really determined attacker can root his device, and install a custom firmware which allows him to control identifier returned by "getDeviceId()". This isn't something that most people would be willing to do, most people would rather find an alternative free app or just buy the app rather than going through that route. Against crackers with that sort of determination and skills, there is not much you can do about.
Alternative avenue of attack would be to replace the public key you ship with the application with the attacker's private/public key combination, and he can potentially write a key generator that can generate license key for the forged application. You can make this attack difficult by self-verification of your own executable.
However, no security scheme is foolproof, java/android application can be reverse engineered and a determined hacker can forge your application and disable its license checks. The only foolproof way to prevent unauthorized usage of an application is to not distribute the application at all.
I imagine you could get 99% of the effect of a more complex scheme with a brain-dead-simple one: just store a file somewhere on the device that indicates that the trial has expired. Granted, tech-savvy users would be able to find and remove the file, but the vast majority won't bother - the device is an inscrutable slab of magic to them, meddling with the internal files might displease the tiny gnomes peddling furiously behind the screen.
You can make things more challenging by hiding the lock file, changing the name and location based on the device id - that way it's a lot more difficult for someone to share instructions on how to evade your trial scheme.
As the other answers have noted: no system is foolproof, there is always someone out there who is cleverer than you and who will relish cracking your scheme. The trick is to not waste your time giving this guy a mental workout and instead cater for the majority.
Sure, but you'll need to be set up to store device identifiers on your own server. On an iphone, you can obtain the UDID using
UIDevice *device = [UIDevice currentDevice];
NSString *uniqueIdentifier = [device uniqueIdentifier];
You might make a database call and acompare uniqueIdentifier to your stored list, ensuring that only one trial can be activated per device.
In android, getDeviceID() gives you a unique device identifier. check the documentation for more info on this.
If I am not missing something, my solution would be straightforward. I will make the expire the service provided by the app, not the app itself. This can be done by using some token mechanism like oAuth. (with an expiring token with a considerable lifetime, in this case your trial period). While the client registration process, I will create the request token as a function of android device id and the requested time. Checkout oAuth, it could be a hassle, but almost all major service providers use it.
How about storing the MAC address of wifi adapter? Possibly on you server and you app will query the server if that MAC is already registered.
WITH USER'S PERMISSION, on the first run of app, query the server if current device's MAC address is already registered? If not, store the MAC address on your server. If already registered, ask user to purchase the app in order to continue using.
This method can be supplemented by some cryptographic algorithms as suggested by Lie Ryan to provide additional security and locks and/or trial period.
I don't know much about iPhone but I believe that every iPhone has wifi adapter and every wifi adapter has unique MAC address. Also check the legal side of this solution as storing the MAC may raise privacy issues/concerns. So, before using this, check laws applicable.

Best way of obfuscating / encrypting form data on the iPhone

I want to create an app which holds sensitive information (imagine it's bank account details, thought it's not). The user enters this information on a form the first time the app starts up. I want this info to be saved, and available, any time the user uses the app (without having to enter a password). However, if the iPhone has a password lock on it, and is stolen, I don't want the data to be easily accessible from the file system.
What is the best way of encrypting or obfuscating the data? There is not a lot of data, just a dozen NSStrings from the UITextFields on the form.
I'm aware there are encryption export restrictions on the iPhone for non-US developers (I am in UK), so I would prefer to avoid going jumping through any of Apple's app submission hoops to get it on the store.
Why not use the built in Keychain Services? That's what it is for.
EDIT: There an article in SDKDevFAQ.com about Keychain Services that points to a tutorial and sample code on github. Also, check out this blog entry about using the Keychain.
I don't know if a jailbroken iPhone device lets you read NSUserDefaults from other applications or not. If not, you could just store your information in there instead of as a file.
Alternatively, you could generate some salt based on (but not equal to) the device ID, and simply XOR it with the bytes of the strings. As long as your algorithm to generate the salt isn't trivial and the strings aren't too long, the data will be fairly safe. Without getting into heavier encryption stuff, you can't guarantee too much more than "fairly safe".

How to avoid piracy in iPhone apps by server side validation?

As par my app requirement, there is a couple of scenarios that I need to handle.
Scenario 1: To avoid piracy, I want to include some piece of code, whose job is sending both IMEI and Serial number of IPhone.
Scenario 2: At server side, I've a database, which has a list of both IMEI and Serial No info. Here I wanna validate both IMEI and Serial numbers. If both are not matched then I can make sure that the app is pirated.
Idea seems good. But I don't know how to handle these two scenarios in my app.
Any help is greatly appreciated.
This isn't something you can do with the iPhone SDK. The iPhone's IMEI or the serial number are not accessible via any API. Also an iPod Touch doesn't even have an IMEI.
Your idea is flawed too. How would you have gotten the IMEI and serial number into your servers database prior to app sending you the details? You can't get these details during purchase because its handled by the App Store and you can't get at that.
If the app was pirated, it would send you the IMEI and serial number anyway, so you can't rely on the app sending them the first time it's run because that would offer absolutely no protection against piracy at all.
The only option you have is to rely on Apple's fairplay DRM. Even though it has been cracked, and there are pirates, it's something you just need to deal with...

Self Deleting iPhone app

I have a iPhone app which needs to have a self destruct option. This app is going to be use on sensitive locations and holds some algorithms which are not to be known by anybody except the iPod Holder.
What would be the most "complete" way of deleting the app?
I was thinking of some how writing zeros to the nib file. or the actual application.app but I believe this folders are write protected and sandboxed.
Anybody have any ideas of better ways to achieve this?
Elaboration (Taken from original poster's comments):
This is for a jailbroken iPhone.
These devices are going to be provided to military personnel this device falling into enemy hands would be the least of my concerns. It's going to have a button so wipe the app once the app is written to zero or better yet corrupted with garbage all over the "exe" the app has no way of working and it would require inspection of the iPod flash chip with equipment that i 100% know the wrong people wont have
If you are openly storing the code that contains this algorithm within your application, there's nothing stopping the "wrong people" from jailbreaking the device and copying the complete file structure of the device before you run your "wipe" process.
Additionally, if you are dealing with a U.S. Government customer, I doubt that they will approve of the purchase of a jailbroken device, given that the vendor of such a device has claimed that jailbreaking is illegal. Whether or not this will hold up in court, the government tends to be conservative in these matters and err on the side of caution. Because Apple is a large U.S. company and a vendor to the government, I wouldn't expect the government procurers to take the jailbreakers' side in this.
My recommendation would be to encrypt the particular algorithms within a file in your application's bundle, and require the user of this application to decrypt this file into memory with the correct (difficult) password. That way, even if the "bad guys" were to gain access to the application, they wouldn't have everything they need to access these algorithms and would have to brute-force the password on the encrypted portion. This could be done on a standard, non-jailbroken device.
The U.S. Army is rolling out iPods in the field, with custom applications on them, so I'm sure that you're not the first person facing this challenge. If this work is being funded through a Department of Defense SBIR grant (or similar), you may even be able to contact your contracting officer and see if they can put you in touch with people at the appropriate agency who may be able to help you out with this (or even determine if it an issue to begin with).
I'm going to go out on a limb here and say you may not want to use the iphone for this type of app. There are intentional limitations to this exact type of action on the iphone and in springboard. If you are doing something so sensitive that it can't fall into unauthorized hands my recommendation would be to use a different and more customizable/controllable platform.
Unless you're working from a jailbroken device, you're probably going to run into problems here.
Even if you can find a way to automatically delete the app, you're still running the risk of those algorithms getting into the wrong hands - you would essentially be running into the same problems that Apple has with jailbreaking - once the device is in someone else's hands, it only takes the proper amount of motivation for the data to be accessed.
The only way to secure your algorithms is to pass the data to a remote server and get the results. There's still a possibility of a security breach, but it's much, much lower.
I don't know how well this would work, but you could store the algorithm as a file inside the application bundle, run the algorithm from that file possibly using a scripting language or something, and delete that file if you need to.
The folders are sandboxed, but your application is in there. On my jailbroken iPhone I see that all the permissions are owned by mobile so I don't see any reason why you can't just overwrite all the files with zeroes and then delete them.
The application bundle is effectively read-only, perhaps you should store some of the information in an encrypted form somewhere on a network.
Even if you find a way to write over the app in the flash memory, you really aren't erasing the app. Flash memory chips use wear leveling algorithms to reduce writes to the same blocks and so when you write out zeroes they are typically written to a new block of memory and not to the same block used before, so you really aren't erasing anything. The data can still be recovered from the flash chip (by a pro).
Another option is to separate out the parameters of the algorithm so that the algorithm is no longer sensitive (or at least not usable) and provide the parameters encrypted in a file. Then provide the key to authorized users via the network and don't store that key into flash, only RAM. They would need to get the key every time they start the app. Only give the key to authorized users. Of course, you'll also need to encrypt that key for transmission over the network with another key... There are systems for doing this, don't invent your own, in any case you'll need a crypto expert to do this right.
I would use the built in encryption to store the data, with a key the user has to enter to decrypt it. Without the key it doesn't matter if the data blob is recovered from the device.