iPhone DEV GUID question - iphone

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.

Related

App with different functionality based on the user's country

I need to develop an application that will behave differently depending on the user's country. Let's say, if the user is in France, some functionality would be available. But, if the user were from India, he would be able to acces a different set of functionality.
If it were only language based restrictions, I could switch functionality using NSLocale class methods. But my functionality is really dependent on the user's country because of licensing and legal reasons.
What are the best practices for dealing with this situation?
For each market where you have specific requirements due to market-specific licensing or legal issues, you can create a separate app in iTunes Connect and make it available for download only in the relevant market. And if you need to, this also allows you to provide a market-specific EULA. It's a big maintenance burden, but it would ensure that only users in a given market can access the app.
Note that in XCode you can fairly easily build, deploy and publish multiple versions of your project built from different configurations (XCode calls this "Targets"), so you could still achieve this in a single codebase by simply adding some preprocessor definitions in the relevant target definitions and putting #ifdef in your code where you want differentiated logic.
A 3rd party app has no access whatsoever to any information about the user of the device or access to the iTunes account. There is no way to know the user's true country. At any given time, the device may not even be associated with any one person. An iPod touch, for example, may have no user logged into any iTunes account. The same device can ultimately be logged into one of several different accounts.
All you have access to is the user's current GPS location (if the user allows your app to access that information) or their current locale.
Basically, there is no way to do what you need. Of course you could prompt the user but obviously there is no way to verify this information.

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

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.

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.

Verifying the purchaser of an App Store application

Is there a way for the developer of an App Store application to tie a sale to an individual user/device ID/Apple account? In other words, a method for the developer to double-check that a specific user has legally purchased the software?
I haven't been able to find a reliable answer to this yet. I'm not looking for specific code examples, just some sort of idea as to how possible (or difficult) this is.
My intent isn't to penalize piracy; it's to be able to provide additional benefits to paid customers. As such, I'm not looking for a way to identify a cracked or pirated version, which I gather has already been solved.
Thanks in advance for any help you can provide!
None of the answers were all the way there, so I'll summarize.
First, as per Tim's answer, Apple does not give you any information to identify customers of a standard app purchase, or to identify one specific sale from another.
However, using In-App purchases provides you with a method to identify a valid purchaser, directly from Apple. The information you receive in this manner is uniquely identifiable; it doesn't give you a user's device ID and/or Apple Store account, but it can be used to verify a specific transaction.
Apple's documentation on verifying store receipts.
You can roll your own system to do this. You're not permitted to look into Apple's information elsewhere on the phone, but you can let your users create an ID in your system, through your application's interface. Gather the information voluntarily from your customer at the time you have them create their Profile on your system. You can get the Device ID, but you may want to collect something like an email address, too, so that you can continue to provide them with consistent service, as they upgrade to a new iPhone, or add an iPad to their fleet of Cocoa Touch devices.
Be sure to use an encrypted http connection when you're talking to your server, so that you don't accidentally expose your customer's information.
To quote "Dr. Touch"...
AntiCrack contains proven technology
to mitigate the risk of your apps
getting pirated by automatic cracking
tools
You do not have access to any purchaser information from the Apple store. Apple considers these customers THEIR customers, not YOUR customers and so will not make any customer identification information available to you...
-t

Enterprise distribution Program for iPhone

I would like to implement a application which backs up all the internal data like SMS, MMS, videos, audios, documents, call history stored in iPhone. But this seems to be not possible with API docs that the apple has released so far ... I have gone through the PDF of Enterprise distribution program and some of the links related to Enterprise Distribution Program, specifies about the Remote wipe and accessing of internal data like Calendar, SMS, MMS etc .... But they didn't mention how to do it programmatically.
Does Apple provide any special privileges like extra API support to access the internal data in their Enterprise Distribution Program?.
Is there any difference between Enterprise Distribution Program and Standard Distribution Program in the development point of view?
And since in-house distribution does not require Apple approval, shall we use some other method which are not officially mentioned in apple docs, to access the internal stored data ..
If so can anyone point out the way to do it?
Any help would be greatly appreciated
awaiting for your response
Best regards,
Mohammed Sadiq ....
You will not get any "bonus api", as there is no api, there's just public one, and private calls. Still, as you will distribute the app on in-house basis, you can use sqlite to get access to sms, calendar, phonebook data. I can't say for sure about other fields, as I don't know the exact permissions of the latest sandbox profile. You definitely can get access to everything on jailbroken device, but that might be not the best solution for you.
Standard and Enterprise are different in that Apple doesn't regulate the apps, as you said, I don't think there are any differences in development (except for what The company needs like internal server access) but there is the difference in distribution. You can't officially get that data programmatically but using undocumented calls sounds like it could work.