Click here to Skip to main content
15,880,392 members
Articles / Desktop Programming / Windows Forms

A method for providing software unlock keys

Rate me:
Please Sign up or sign in to vote.
4.76/5 (27 votes)
23 Feb 2009CPOL4 min read 86.2K   1.5K   170   23
Here is a very simplified method for selling relatively secure unlock keys to your customers. The unlock key you provide will only unlock that specific customer's download instance for a specific feature set or product.

Introduction

This is my first article posting to CodeProject.

I needed a quick way to sell a small, inexpensive WinForms application from my website; either after the customer completes a free trial period, or when purchasing at download time. I wanted to provide the customer with the following scenario:

  • Customer comes to my website and downloads the setup package as a free 30 day trial (by default, the software behaves in trial mode unless an unlock key is purchased and entered).
  • Customer decides if they want to buy it or not.
  • If customer decides yes, then they purchase an unlock key from my website, providing me with the serial number of their copy of the software (or they download a new copy and purchase the key all at once).
  • Customer is emailed the unlock key that unlocks the following:
    • The specific software copy they downloaded (based on the serial number).
    • The software they purchased (based on their name).
    • The software provided by my company (based on my company name).
    • The software feature set they purchased (based on what they bought).
  • All of the above must be true for the emailed key to actually unlock the software.
  • User is now in possession of an unlocked software and a key that cannot unlock any of my other products. They can freely re-install the software on multiple machines, but the key will only unlock the copy they downloaded.

Background

This is a very common way of purchasing software that we are all familiar with. The method presented here is as secure as you are able to keep your company cipher keys. See other articles at Microsoft on how to obfuscate cipher keys in your deployed applications. 99.99% of people don't have the time to spend hacking unlock keys. Of the remaining .01%, how many of those are going to give away a hacked key to thousands of people? Also, since this method hashes all of the following items, any hacker would still need to know these things to create the keys for other people's copies. Additionally, your software company can easily invalidate all the keys floating around in the marketplace by simply changing one of the items in the hash. Most likely, it would be the product feature. The following items are hashed into the unlock key:

  • Company name
  • Customer name
  • Serial number of the software downloaded
  • The product or product feature code

By extending the classes, you can hash even more information like machine MAC address if you want to restrict unlocking to only a specific computer.

Using the code

As you can see from the demo program, the code is ultra-simple and self explanatory once you open the solution file. The following code is deployed to your web site to make the key. Note: btnSell_Click is deployed only to your website, not the product you are selling. This is the code your website needs to create an unlock key after your customer pays for the desired product.

To give the customer a key, they must know two things:

  1. Their name.
  2. What feature set or product they want to purchase.

Your website must know these two things:

  1. The serial number of the copy of the software the customer just downloaded (optional; if you are not serial stamping your downloads, then just leave it blank, but the key won't be as secure; otherwise, create a serial number and download that to the customer to the config file or the DLL itself.) Hint: environment.tickcount makes a good serial number.
  2. The name of your company (of course, your website code knows this).

After you create the key, email it to the customer so they can use it to unlock the software they just downloaded.

VB
Private Sub btnSell_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles btnSell.Click
    Try
        ' Create the key making/selling object
        Dim locKeyHandler As OMBKeySell.KeySeller = _
                          New OMBKeySell.KeySeller(_MyCompanyKey, _MyCompanyIV)
        ' Make the key which can only unlock a specific customer name,
        ' for a specific downloaded serial no, for a specific product,
        ' for your specific company name (key is a hash of all these taken together)
        txtSellKey.Text = locKeyHandler.SellKey(txtSellCompanyName.Text, _
                          txtSellSerial.Text, txtSellCustomerName.Text, _
                          CType(btnSell.Tag, Key.ProductOrProductFeatureSet))
        ' In real use the key would be emailed at this point
        ' and not simply placed in the clipboard
        My.Computer.Clipboard.SetText(txtSellKey.Text, TextDataFormat.Text)
        ' Thank the customer and inform them of what they just bought
        lblSellStatus.Text = "Thank you for purchasing our software, " & _ 
                             "your unlock key has been placed in your computer " & _ 
                             "clipboard, paste it below to activate your copy " & _ 
                             "of the software." & vbCrLf & vbCrLf & _
                             "(In real use the key would be emailed)"
        lblSellFeature.Text = "You just bought a key to unlock this " & _ 
                              "feature or product: " & CType(btnSell.Tag, _
                              Key.ProductOrProductFeatureSet).ToString
        ' Clear buy side of the demo form
        lblBuyStatus.Text = ""
        lblBuyFeature.Text = ""
        txtBuyCustomerName.Text = ""
        txtBuyKey.Text = ""
    Catch ex As Exception
        lblSellStatus.Text = ex.Message
        lblSellFeature.Text = ""
        txtSellKey.Text = ""
        txtSellCustomerName.Text = ""
    End Try
End Sub

The following code is deployed to your product to validate the key and provide your program with the product or product feature that was purchased. Note: btnBuy_Click is deployed only in the product you are selling, not in your website. This is the code your purchased software needs on the product unlocking form.

For the customer to unlock, they must know two things:

  1. The name they used as their name when they made the purchase above.
  2. The key that was emailed to them.

Your deployed software must know these two things (embedded into the software or the config file):

  1. The name of your company (same name used by your website code when you created and sold the unlock key, embedded in the code or config file of the downloaded package).
  2. The serial number of the copy of the software the customer just downloaded (embedded in the software or downloaded config file).

After you process their key, place the provided product feature code in the Registry. Now, your program looks at that Registry key to determine how/if it should run itself.

VB
Private Sub btnBuy_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles btnBuy.Click
    Try
        ' Create the key consuming/buying object
        Dim locKeyHandler As OMBKeyBuy.KeyBuyer = _
            New OMBKeyBuy.KeyBuyer(_MyCompanyKey, _MyCompanyIV)
        ' Validate the key, if its valid then the feature set it unlocks
        ' will be returned, if invalid then various errors are thrown
        Dim locFeatureBeingBought As Key.ProductOrProductFeatureSet = _
            locKeyHandler.BuyKey(txtBuyCompanyName.Text, _
            txtBuySerial.Text, txtBuyCustomerName.Text, txtBuyKey.Text)
        ' At this point your deployed software should place the feature
        ' set code in the registry, your program then checks the registry
        ' for this enumerator to determine how/if it should run (dont place
        ' the key string itself in the registry
        ' as that should only live in the customers hands)
        '    registrykey = locFeatureBeingBought
        ' Thank the customer again and tell them
        ' what feature or product their key just unlocked
        lblBuyStatus.Text = "Thank you for purchasing our software, " & _ 
                            "your specific copy of the software is now unlocked"
        lblBuyFeature.Text = "You unlocked this feature or product: " & _
                             locFeatureBeingBought.ToString
        ' Clear sell side of the demo form
        lblSellStatus.Text = ""
        lblSellFeature.Text = ""
        txtSellCustomerName.Text = ""
        txtSellKey.Text = ""
    Catch ex As Exception
        lblBuyStatus.Text = ex.Message
        lblBuyFeature.Text = ""
        txtBuyKey.Text = ""
        txtBuyCustomerName.Text = ""
    End Try
End Sub

The demo program (is in the zip)

To use the demo program... make a key on the top half by entering your name. This simulates your purchase at a website. Then, to simulate unlocking your software, enter your name and paste the key. The unlocked feature will be returned.

screenshot.jpg

Points of interest

I had a hard time finding code samples for unlock keys on the Internet that suited my purpose and that were not too complicated.

History

  • First posting.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
I am a 54 year old software developer working non-stop in the field since 1979. Back then I was converting autocoder to a more high level language called assembler language (BAL) on mainframes Smile | :) Today I am a lead technical analyst for a large manufacturing company working on the .NET and IBM Java platforms. In the 29 years between then and now I have probably coded in most every language and designed software for a wide variety of applications and platforms.

Comments and Discussions

 
QuestionAre you the Rick Hansen who used to work at Artemis Alliance? Pin
CMJobson24-Mar-09 7:46
CMJobson24-Mar-09 7:46 
AnswerRe: Are you the Rick Hansen who used to work at Artemis Alliance? Pin
Rick Hansen24-Mar-09 14:04
Rick Hansen24-Mar-09 14:04 
QuestionDid I miss something? Pin
Jason Christian24-Mar-09 6:03
Jason Christian24-Mar-09 6:03 
AnswerRe: Did I miss something? Pin
Rick Hansen24-Mar-09 6:10
Rick Hansen24-Mar-09 6:10 
GeneralYou dont provide the code Pin
jamesklett24-Mar-09 4:35
jamesklett24-Mar-09 4:35 
GeneralRe: You dont provide the code Pin
Rick Hansen24-Mar-09 4:49
Rick Hansen24-Mar-09 4:49 
GeneralGood article. Pin
ykachanov2-Mar-09 16:17
ykachanov2-Mar-09 16:17 
GeneralSerial stamping your downloads? [modified] Pin
Terence Wallace2-Mar-09 11:37
Terence Wallace2-Mar-09 11:37 
GeneralRe: Serial stamping your downloads? Pin
Stumproot3-Mar-09 0:38
Stumproot3-Mar-09 0:38 
GeneralRe: Serial stamping your downloads? Pin
francoisdotnet3-Mar-09 20:30
francoisdotnet3-Mar-09 20:30 
GeneralRe: Serial stamping your downloads? Pin
Rick Hansen4-Mar-09 4:01
Rick Hansen4-Mar-09 4:01 
Thats the easy part...

When the customer comes to my aspx page to fill out the information form and presses Submit...

I use the System.Reflection.Emit framework class to build a small dll file that contains nothing more than a single public constant (double), that constant is initialized to the current Environment.TickCount value. I use the Save method to save that dll to the customers folder (every customer that applies at the site gets a working folder made for them).

Then I use the Sharp Zip library to make a self-extracting setup package of that dynamic "serial number" dll and all th other dll's, exe's etc that the installation requires.

The use downloads the zip package, runs the setup.exe program, the dynamically created dll is comied to the application root along with all the other dll's and exe's. The project has a reference to the dynamically created dll to get the dynamically stamped serial number.

To obfuscate that dynamic dll for amateur hackers I name it something completely unrelated like "AudioProcessingLibrary.dll" but it really is just my stamped serial number class.

Hope this helps.

I didnt want to include all this in my article, but I guess I should have at least pointed people to Reflection.Emit and creating dll's on the fly.

This article will get you started:

http://msdn.microsoft.com/en-us/library/system.reflection.emit.assemblybuilder.aspx[^]
GeneralRe: Serial stamping your downloads? Pin
Stumproot4-Mar-09 5:54
Stumproot4-Mar-09 5:54 
Generalgood try Pin
Donsw24-Feb-09 5:45
Donsw24-Feb-09 5:45 
GeneralRe: good try Pin
Rick Hansen24-Feb-09 6:13
Rick Hansen24-Feb-09 6:13 
GeneralRe: good try Pin
francoisdotnet3-Mar-09 20:41
francoisdotnet3-Mar-09 20:41 
GeneralRe: good try Pin
Rick Hansen4-Mar-09 4:52
Rick Hansen4-Mar-09 4:52 
GeneralRe: good try Pin
RTS@WORK3-Apr-09 3:57
RTS@WORK3-Apr-09 3:57 
GeneralMy vote of 2 Pin
Member 329956924-Feb-09 4:57
Member 329956924-Feb-09 4:57 
GeneralRe: My vote of 2 Pin
Rick Hansen24-Feb-09 6:03
Rick Hansen24-Feb-09 6:03 
GeneralRe: My vote of 2 Pin
Sean J Conway26-Feb-09 10:53
Sean J Conway26-Feb-09 10:53 
GeneralRe: My vote of 2 Pin
Rick Hansen28-Feb-09 6:48
Rick Hansen28-Feb-09 6:48 
GeneralRe: My vote of 2 Pin
GerhardKreuzer25-Mar-09 19:55
GerhardKreuzer25-Mar-09 19:55 
GeneralRe: My vote of 2 Pin
RTS@WORK3-Apr-09 4:04
RTS@WORK3-Apr-09 4:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.