0

I am researching software authentication methods that are easy yet secure to implement in my own projects.

IDEAS: Steps to authenticate apps

The application is running from a USB drive as it is never installed on any one computer.

  1. Upon each run, the software starts up Information such as USB Hardware ID and perhaps an ID unique to the app is gathered and somehow securely hashed into an activation key-like string.
  2. This string is then passed as a parameter into a PHP function where it is reversed (server-side) and content checked against a database to verify that the application was run from an 'authorized' USB key and not copied from one to another (as H/W ID would change and not match the one in the database) - effectively this would minimise the chance that a client gets two working 'software licenses'.

Questions

The idea is to be able to retrieve the columns for the row in the database, which matches that particular HW ID and unique app secret will locate the correct row. The PHP is used to check if further entries in that row are also matching other values such as whether the HW key is expired or not. However, to prevent the user from using that same string parameter every time, it should be random and near impossible to calculate/guess, yet link to the same location in the database.

I am now considering encryption instead of hashing (for the benefit of maintaining the data), as it can be decrypted using a master key at the server. I understand that hashing only converts in one direction and perhaps I wasn't expressing the scenario correctly before this edit so I hope things have become a little clearer. Could someone guide me in the right direction? How is this done?

I'd really appreciate any feedback and ideas on how to make this happen properly.

ProGrammer
  • 111
  • 3
  • 1
    In this new spec, it's pretty straightforward: you embed your public key in with the software, concat the data you want with a new random string each time, then encrypt the data with the key. Server-side, you decrypt, dump the random string, and use the data you want. – schroeder Nov 24 '17 at 10:08
  • @schroeder I can follow vaguely, so you are recommending encryption over hashing, correct? How would I best go about generating this key pair properly and where would I store the private key - in the php script itself? – ProGrammer Nov 24 '17 at 10:45
  • Because you want to create a string that is unique, hashing will be impossible (same string every time). How to generate and utilise keys server-side is a pure programming question with multiple solutions available to meet your requirements (whatever they might be). – schroeder Nov 24 '17 at 11:02

1 Answers1

1

You want a string that is unique every time the registration key is checked and something that the user will not be able to easily reverse engineer (and thereby bypass your DRM restrictions).

One way to do this is to have the application store your crypto key. You concat/combine the software keys, IDs, and whatever other data you want, along with a random string that changes every time this data is accessed/requested. You encrypt this with the crypto key and pass to your server. The server decrypts with its crypto key, extracts the decrypted data and dumps the random string.

  1. The use of the random string means that the resulting cyphertext string is unique each time, making it difficult to reverse engineer.
  2. Encrypting means that you can read the plaintext data even though the cyphertext is different each time (a feature that a straight hash cannot provide).

The downside is that the cyphertext might get large (depending on how you do it). You should also make sure that the random text is of a variable length to further make it difficult to guess the component strings.

The other problem you will have is the proper handling of the key in your app. Once a user gets that, then they can craft their own strings that will pass your tests.

In general, you are asking about how to devise a DRM solution. There are lots of established ways to do this, and I recommend you look at their design patterns.

The common struggle is that once you place your app in the hands of a user, then you lose a lot of control. It is better to design your solution so that it does not matter if a user copies your software, or design a framework upon which your app runs instead of locally (which is way web-based apps are so popular). You also have to weigh the cost/benefits of all this design work against the work a user will have to go through to defeat it. Are you placing your efforts in the right place?

schroeder
  • 123,438
  • 55
  • 284
  • 319
  • That is a great way to achieve the result I am looking for. I am still finetuning the correct solution but thus far your response has gotten me off to a good start. I have connected it with my implementation question: [read it here](https://apple.stackexchange.com/questions/306816/encrypting-data-string-using-public-key-then-save-to-variable) using OpenSSL and a public/private key pair I generated. – ProGrammer Nov 25 '17 at 10:49
  • @ProGrammer if this has been useful, consider upvoting or accepting as an answer – schroeder Nov 25 '17 at 12:54
  • All encryption schemes considered acceptable today for user data (asymmetric RSA EG IES, symmetric AES-CBC AES-CTR AES-GCM AES-CCM etc but _not_ AES-ECB) already randomize the encryption and you don't need to add your own. Even the original RSAES-PKCS1v1_5 (aka type 02) which was broken by Bleichenbacher. But if the encryption (public) key is on the USB, a cheater can read and use it. – dave_thompson_085 Dec 25 '17 at 06:31