0

I have an application in C# where several users access it.

Each user will have a serial key associated with his username in a table users in a local MySQL database.

Example of the table users:

  • User 1: Alan Serial Key: AAA-AAA-AAA
  • User 2: Bart Serial Key: BBB-BBB-BBB
  • User 3: Mark Serial Key: CCC-CCC-CCC

These keys are also saved on my remote MySQL database. When the program starts, after logging in, I would check that the key is active and valid.

I can deactivate/delete the keys whenever I want from my remote database.

The questions

  1. What is the best way to verify that the key is active and used only by one user ?
  2. How can I verify that the same user only login from one PC at a time?
  3. If there is no connection for a few hours, how can I make the software work the same? Maybe checking only once a day?
  • If you want to verify if the key is active, you query the data. To check if a key is used only by one user, you can either query the data (and decide what to do about it), or enforce a constraint that a key is not assigned to multiple users in the first place and reject any attempt. As for ensuring only one logon at a time, is it necessary to enforce that strictly and in real-time? The easiest solution to a problem like the latter one, can be not to create a problem unnecessarily. – Steve May 29 at 12:05
  • @Steve I need the user to be used only once per instance. There cannot be two identical users connected at the same time – Lorenzo Belfanti May 29 at 12:16
  • 2
    The industry hasn't come up with a very good solution for this in several decades, so you may want to concentrate on something that's more likely to give you more value for the time used. – Kayaman May 29 at 12:33
  • 1
    Lorenzo, as @Kayaman says, there isn't a good general solution. You can bar a person from logging on again, if they already remain logged on, but then as you recognise there are going to be problems when a user doesn't explicitly log off, either through user error or through a dropped connection/application crash/machine failure. You can poll, allow operations only whilst the last poll remains valid, and log the user off on both sides after a waiting period if the poll fails, but a robust implementation will not be trivial. – Steve May 29 at 13:05
1

One approach is

  1. Application requests a license key at startup, attach either a random or hardware based id and the username to the request. The server finds the appropriate key and marks it as used, with the id and other relevant data. This can be done by using a separate 'used licenses' table or by updating the licese key row.
  2. Application sends a keep alive message to the server at some interval (a minute?). If there is a missmatch between the id in the keep alive message and the used license the application is told to terminate.
  3. If the server cannot be reached for some amount of time ( a few hours?), the application might terminate, display a warning, or just continue running.
  4. If the server does not get a keep alive message for some time it should release the key. This is to prevent an application crash from keeping the key forever.

This ensures only one concurrent application instance per key. The behavior if a user tries to launch two instances is up to you. You might want to re-assign the key to the later instance, causing the original instance to terminate, or reject the request, preventing the new instance from starting, or let the user decide. Benefit of using a hardware based ID is to allow multiple instances to run on the same computer (if you want to allow it). It would also allow restarting the application after a crash without waiting for the key to timeout.

If this scheme is meant to support multiple independent installations at different companies a two stage solution could be used. This reduces the dependence on the remote server, but reduces your control somewhat.

  1. Local server fetches all serial keys from the remote server every day and replaces the old keys. Keys are valid for a short while (a week?)
  2. Local server implements behavior above.

You could also allow the users to lock a license key to a specific machine. That machine could then run the software without internet connection, but the user cannot run the software from any other computer.

Note that this does not provide strong guarantees. A determined attacker will almost always be able to break systems like this as long as all important logic is run on the attackers computer. The goal is usually to increase cost of abuse to more than what a license costs. You might also want to monitor the system to detect patterns that might indicate systematic abuse.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.