views:

326

answers:

10

I am developing a program that I want to share with certain people, however if I change my mind about these people I want to be able to 'revoke' their access to the program.

Ideally this would be on a per-user basis rather than just blocking all instances of the program. Something along the lines of user accounts, but at the moment I don't really have access to a server where these accounts could be authenticated so a simpler method is probably in order.

Am I being too ambitious?

(If it is relevant I am using Java.)


Sorry, I missed a few relevant details:

The application will be used almost entirely online. I don't expect the userbase to be far over 100 (and that is ambitious), if there were more than 100 users I would splash out on an authentication server of some sort, however the closest thing to this I have at the moment is a basic FTP server that I could store files on.


Thanks for all the answers, its a shame that SO only lets me choose one best answer. :) Thank you guys.

+2  A: 

If your program relies on network access to information via web services or some other mechanism you could simply black list the user accounts that you wish to shut off.

If it is a completely offline application you are SOL to the best of my knowledge. The only control you have over the application after deployment is through network requests to resources you still control.

EDIT

Far from flawless, but as a second thought, in an offline application, and only for less technically proficient users you could attempt to control access to the application through an update mechanism that would invalidate the application through an encrypted list of user names, etc. Though that is easily circumvented, and possibly reversed since all that information is stored on the clients machine. And it relies on them allowing you to update the software.

Matthew Vines
A: 

Every user could have a unique username and you can check it against a webservice, to see if that particular user still on grace list.

Rubens Farias
+1  A: 

Since you don't have access to some kind of independent resource for the user to authenticate against, the only answer I can think of is a "dead man's switch", whereby you send the user a license file at a specified time interval. The application "expires" at this interval and must have a new file in order to run. Don't want the user to use the software? Don't send them a new file.

This is sub-optimal, for a number of reasons:

  1. All your users will have to receive this file on schedule, which will make lots of support work.
  2. Since the system lives entirely on the user's machine, circumvention measures will range from trivial to "hassle", but will always be possible. This will vary with the algorithm you choose for encryption and delivery of the file.
  3. Some non-zero number of users will be "false positives" and their installations will stop working because of some mistake in the process.
  4. If you don't build in user-specific info in the file, users will be able to share it with each other.
Chris McCall
+1  A: 

The usual way is to provide a license file that allows the usage for a certain period. After that period, the users would have to request a new license file. To that's the only way if you want to allow usage without direct connection to a server. But it is annoying for all parties - the users are forced to request new license files and you are forced to create and distribute them.

Authentication against a server is possible, but, as long as you're using java, not too secure. Even if you obfuscate the code, it's possible to remove the authentication part from the application or to sniff the authentication traffic and just build up a mock server to permanently enable the software. You can prevent it with cryptographic methods, but it's getting more and more complicated.

The easiest way to keep close control is to provide at least parts of the application as a service - but that of course requires a server.

Andreas_D
May I ask why authentication against a server is not secure as long as I use Java? Is java byte code easy to reverse engineer?
Ben Page
Java byte code is easy to reverse engineer unless obfuscated for an experienced programmer.
Thorbjørn Ravn Andersen
@Ben - look at this one: http://java.decompiler.free.fr/ (btw - to a MUST for every Java devolper), and you know what I mean ;)
Andreas_D
+1  A: 

Without a server-side component, what you are asking for would be difficult and unreliable.

The best way to guarantee that you can revoke access to your software is through an Internet-based "software as a service" application. If you don't provide access, they're not using the software. If it is a desktop-based application, then some key piece of functionality would still have to be on an online server somewhere.

If the user has the entire application on their local machine, it can be reverse engineered and "cracked" in some fashion. The only way to overcome this is to assure that some part of the functionality is never on their machine.

Robert Cartaino
I thought this would be the case but was hoping otherwise. Does the situation change at all if I have access to a HTTP server (nothing dynamic like PHP though).
Ben Page
+1  A: 

Generate serials based upon CPU hardware IDs. Have periodic updates to your program and hard code blacklisting of certain CPUS ids into it. Of course, you'd have to make your program expire if a periodic update has not been received.

stormist
Have you done this before from Java, and do you know if there is a cross platform way to do this?
Ben Page
I've done it from C#. A quick google shows that its a bit more complicated in java but not impossible. as far as cross platform, looks like you'd have to code for each platform
stormist
+3  A: 

There is no way to do this with a 100% guarantee. Except for a hardware solution (which can also be worked around) the software is manipulatable.

As a very simple example, take a Windows program (Java is even easier) that checks the date to see if it can run (think trial ware). Even without setting the clock back you can defeat it - figure out what calls it is making to check the date and then provide an alternate DLL that changes that call to always return a date that will work.

If you go with a server that the clients have to connect to that will work better, since you can do all validity checking server side. But you cannot simply return a true/false thing since you can then change things at the network level to alter the false to a true. To work around that you would need to use SSL to encrypt the network traffic.

The "better" (off the top of my head) is to have the server do the work of the program and just have the program display the results. Then for clients that do not have access the server just refuses to return results to them.

TofuBeer
This is why sealed jars exist.
Thorbjørn Ravn Andersen
Yes... nothing stops you from unjarring it and using the classes that way or rejarring them without the sealed portion of the manifest... or using bytecode instrumentation to change what is called... etc...
TofuBeer
A: 

Each month have the user be required to enter a new user name that matches the user name for the corresponding month that is stored in your program. If you want to stop a user from using your program simply stop sending them the new user names and they will not be able to use the program after the end of the month.

Lumpy
+1  A: 

I guess this is an actual application running on the users machine.

The simplest approach I can think of is to use Java Web Start which can ensure that your application downloads jars from the internet if you update them. This includes a license which is per user (i.e. the jnlp file depends on the user downloading it including the correct jar) and that license should allow the user to work for a number of days with your application even without internet access after which a new license must be downloaded (as the JNLP file has changed for that user). Note: Be CERTAIN to change the URLs of a changed license file, otherwise the java cache may be corrupted.

The license file can just contain a single class which looks at the date and says true/false to continue. It must be suitable signed to create sealed jars.

More advanced schemes exist but this will work, be simple to maintain, and be a reasonable compromise between allowing free distribution and hardcore license schemes.

Thorbjørn Ravn Andersen
+1  A: 

Don’t bother. As long as you distribute the actual software to clients there is always a way to work around any schemes you can think up. In the end it will only make your software less reliable and more cumbersome to work with so that prospective customers are scared away—everybody loses.

Bombe