How would I go about licensing a WPF windows application

Burt picture Burt · Jun 11, 2010 · Viewed 10.8k times · Source

I have developed a small application that I would like to try and sell but I am unfamiliar with how best to go about this.

  1. How would I go about locking the program down for trial use1.

  2. How would I go about dealing with accepting payments?

Bearing in mind that I am a one man band with not a lot of money, I was hoping for a solution that would be free or a low cost, effective, secure and simple to implement and maintain. This is not something that I have a lot of experience with as I have typically developed for the public sector where they buy a solution as a whole and we have never licensed it.

Any help would really be appreciated. Thanks,

B

Answer

Swingline Rage picture Swingline Rage · Jun 11, 2010

I can tell you how I do it. Disclaimer: your mileage may vary. This is for the case of preventing casual piracy of a simple WinForms or WPF or other desktop app. It's not particularly robust or secure against sophisticated cracking, but it does a great job of preventing casual piracy.

  1. For licensing, I tried several 3rd party solutions. They're all fairly easy to use for the nominal case of preventing casual piracy, which of course if the only piracy you should really be concerned about.

  2. What I found was that none of the licensing providers were really compatible with the existing payment processors / gateways. There are a few "all-in-one" solutions but the level of technical debt there was unacceptable to me (a freelancer and sole developer). I was looking for a simple way to go from a "Buy Now" link on a website to unlocking the desktop software after purchase. Some of the existing "all-in-one" solutions are overkill for this purpose, some ignore the "purchase" aspect entirely.

  3. I ended up using Xml Digital Signatures to sign license files with the application's private key, which is never distributed to users. The result: you have a .LIC or .LICX file on the target machine that users can read (it's plain text, except for the enveloped signature) but not modify. (Or rather, they can't modify it without you knowing they've modified it.) This little file is the key to the whole system.

  4. When the application loads, it verifies that the XML signature is valid (using the application's public key, which is distributed with the app) and if it's valid, it reads the information from the license file, and enables/disables certain features based on that. For example, your license file could contain a product expiration date, or a couple pieces of unique machine info (be careful, always, not to inconvenience your legit users with this...you don't want them to have to reapply for license keys every time they change out a hard drive).

  5. As an additional (and slightly more invasive) step, you can have the app connect to your server, though this gets you into server downtime issues and so forth and so on. Some devs are willing to put up with this, others aren't.

  6. Now for the purchase part, there are many many options. Paypal is far and away the easiest. You may or may not like their rate plans, but it's an absolute cinch to get up and running with Paypal.

  7. For that you want a Premier or Business account, not a Personal account. Note: in the Paypal docs it sometimes says you need a Paypal Business account. Whenever they say that, they actually mean, "a Paypal Business or Premier account".

  8. Now get yourself a product website and customize your Buy Now buttons etc. When the user makes a purchase, your website will receive a ping from Paypal IPN, which is their notification service. This ping is just a call to a defined HTTP endpoint on your website, and it contains all the information you'll want about the purchase. Mainly, the user's email...

  9. (Okay, I feel like I should mention: Paypal along with most other legit processors have a "sandbox" where you can test all this out before going live. Does wonders towards giving you the warm fuzzy about actually going live, with money on the line.)

  10. Which you'll use to auto-send the user an Activation Code after purchase, so they don't have to wait 24 hours for you to manually send them a code. Store this activation code (which under this scenario can be any unique, difficult-to-guess number, such as a GUID, prettified or not) in the DB with a usage count which you'll track to detect duplicate codes.

  11. The user enters the Activation Code into the software, via a screen you provide.

  12. The software contacts the server over https (this is a one-time thing that happens only when the software is unlocked), and says, "hey, is this license code the user just gave me valid?"

  13. If the supplied activation code matches the code stored in the database at the time of sale, and that activation code hasn't yet been confirmed, then Success!

  14. The server then needs to build the license file, which is an extremely simple XML or text file containing "what this copy of the software is allowed to do". There's no standard for what it should contain, only a few conventions.

  15. The server signs the license file with the application's private key and returns it as a data stream to your application...

  16. Which saves it as a .LIC or .LICX (or whatever extension you want) file, which it then checks on load time as per Step 3.

This has worked really well for me, and it's a cinch to implement. The key to the whole thing is simply: trust those XML DSigs. When the LIC file is missing, you default to trial mode. When the sig is modified, you switch to trial mode. Only when the LIC file is present, validly signed, and contains the right information, do you then (in code) open up access to "full" functionality.

Also, interperse more than one license-check point in your code. I do one at app startup, another at idle, and another just before entering key functional areas. So if someone does reverse the code, and they can, they'll at least have to do a bit of searching to gut all the license checks. Of course, nothing you can do can prevent people from patching their way around those checks. You just want to make it a bit more difficult.