Password login for ios app - iphone

I am currently developing an app for a company that is in a very competitive field. I have finished all of the features of the app that they requested except for one, making it somehow protected from their competing companies to download and use. I thought that I could set up a UIViewController with a password field that would check against some kind of database, but I'm not sure how to do the checking against a database part nor the practicality of it, and was hoping I could get some ideas on how to do this so that other companies couldn't steal and use this app without a password or something that changes like every 30 days or something and is kind of like an activation code.

Review the WWDC 2012 video "Building and Distributing Custom B2B Apps for iOS". I'm unsure if your app is in this B2B classification, it seems that it might be from your description.

What I ended up doing (if everyone needs a reference) was setting up a server with an SQL table that has pass codes in it. Since apple does not allow for any sort of system that requires you to "buy the app from outside the app store" I made a dumby username field (shame on me) that takes any value you like and then requires to have a pass code that fits. Once the pass code gets authenticated with the web server in a json sql request (there are plenty of api's to do this with) it comes back and sends the user to the first screen and sets a value in a plist with how many days of use the user has left. Whenever the user opens up the app it checks to see if the date is different from the last date logged in (saved in the same plist file) and if it is different then it calculates the difference and deducts that many. When the count reaches 0 it sends the user to the pass code authentication screen again. A bit complicated but an effective method of getting around Apple's restriction on not having a sort of pass code system like this. Thanks for the answers, unfortunately enterprise did not work for this company since they needed to be able to distribute the app to as many 3rd party members as they wanted to without having to worry about them leaving the company for other suppliers and remote management of the app (I.e ability to remote uninstall) was also not an option. Hope this helps someone someday!

Related

Facebook application load and performance testing

So I've hit a bit of a dilemma with my application load testing. My application relies on valid Facebook logins as I create shadow records that correspond to the users who log in.
How can I load test my application while using Facebook calls (rather than disabling).
I need to ensure at least 100,000 users can connect without getting bogged down.
My code runs fairly fast so far on since loads I'm averaging 1000 ms pre-caching. But I'd like to do some more load testing before I turn on my cache.
How can I do this?
From what I've come across, everyone seems to say just turn off Facebook calls and load test as if the application was a regular site. Also, I came across something called friendrunner which seemed like it could be the solution to my problem. Except no one from there has gotten back to me as of yet.
You can't. Or rather, you really shouldn't and probably can't anyway. Facebook is one of the more aggressive sites when it comes to introducing measures designed to prevent synthetic (scripted) interaction and if you try to get around these measures you risk Facebook taking measures against you (probably not legal, but they can surely suspend your account and if you have a corporate agreement with them it could get embarrassing).
But this shouldn't be an issue for performance testing. You simply need to spoof the Facebook calls and focus on writing scripts that only call the servers that you want to load test. This is best practice for any project. In the past, I have simply used random strings to simulate the Facebook account id and, where you application requires certain user information from an account, you will need to be slightly more creative and stub this out. As far as I can tell, friendrunner is just that, a Facebook stub.

Way to expose appstore IDs but keep them secured for release

I am working on an application that will allow the user to purchase content from the app store
https://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008267-CH1-SW1
These products require a "ProductID" that ties them to whatever is in the appstore.
I will need to store these IDs somewhere in the application so I know what to send the server when the purchase button is clicked.
I wish to expose these ID's and allow non-programmers to enter any ID they want in both our side and the server side, and not have to call on a programmer to go into the code and change some enum.
I figured a config file would not be very secure, for in the end it's just a text file that a user could potentially view after purchasing the app. May not be a huge problem if a user saw the ID, but I don't like the idea of anybody seeing the innards that go through a payment process
Assuming im making sense here, whats a good way to expose these IDs but still keep them secure so users may not find them?
Also curious, how secure is something like an enum in c++? Can people break the .exe down and see the code and its values?
For your final question, yes and no. If they have access to the debugging information (a PDB in Microsoft land) then yes. But armed with just an exe and disassembler, you will see only the constant values that are assigned to the enum members.

Persistence on an online click once application

Is there a way to persist an string from an online click once application. I saw something about isolated file storage as answers to other questions. But none of them specify if it works also for online apps (I really don't think so).
I think that something like a cookie will work. Is there something like that available?
The application must run only online (is triggered with some parameters), but for each user it needs to save a file with specific information asked to him. Once the app runs for the very first time it must not ask for that info to the user.
Thanks.
You can store the information in LocalApplicationData. Just create a directory with either your application name or your company name, stick the string in a file, and read it from there. This article shows you how to persist this data, and not have it impacted by ClickOnce updates. It will work even though your application is online-only. (Online-only C/O apps are still installed, it just means it always runs it from the URL, and requires the user to be connected in order to install the app.)

Manage country wise databases on different servers in iPhone App

I have current a developed app which I am going to submit in just few days .
Currently The Application shows data by calling a web service and fetches data from a server .
Now client requirement is to build two different databases.
So the question is should I make two different builds for two different countries or should I make alternative call to the web services based on the format region selected in the iPhone .
e.g, if ( country == uk ) then
call uk_Service;
else if( country == us ) then
call us_Service;
Please tell me which approach is better. And also if should I make two different builds then can I submit both of them at a time in the AppStore .
Thanks
I don't think it is a good idea to have two different builds for the App Store. This would mean that you have to do all the organisatorial overhead in iTunes Connect twice. For example an update with all the screen shots and textual descriptions have to be submitted twice. Also you do not have a chance to ensure the release of both submissions will be synchronous.
Why don't you provide a setting to the user where he can choose the country he wants to use your app for?
I would go with the if/else option purely because maintaining 2 apps instead of one will be more work - eg when you want to fix a bug you'll have to do it twice over. Another advantage of using the localised version is that a user can change their localisation and start using the correct database - eg they buy the app in the US and then move to the UK, change their settings and can start using the UK database without a problem

How would you keep secret data secret in an iPhone application?

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.