Click here to Skip to main content
Click here to Skip to main content

Protecting Your Software Using Simple Serial Number/Activation Key Pair

By , 12 Aug 2008
 

act.JPG

Introduction

In this simple article, I am going to show how you can protect your software from unauthorized copying by creating a serial number/activation key pair based on the physical address (MAC) of the network adapter on the client's machine.

Getting the MAC Address and Generating the Serial Number

The first step is to get the MAC address of the client's machine. This could be achieved by using the ManagementClass class located in the System.Management assembly. We have to add a reference to that assembly to our project, and import it into SecurityManager.vb, which will be the class in which we place the GetSerial() and CheckKey() functions. These two functions will be responsible for generating the serial number from the MAC address and checking whether the key entered by the user is valid. As a first step, we define the GetSerial() function as follows:

Public Function GetSerial() As Long
    Dim mc As New ManagementClass("Win32_NetworkAdapterConfiguration")
    Dim mac As String = ""
    'Getting network adapters collection
    Dim moc As ManagementObjectCollection = mc.GetInstances

    'Here we iterate over available network adapters, 
    'picking the first possible one
    For Each mo As ManagementObject In moc
        If mo.Item("IPEnabled") Then
            mac = mo.Item("MacAddress").ToString
            Exit For
        End If
    Next

    mc.Dispose()

    'This is a simple function that we use to get a serial out
    'of our MAC address. Say that x is the MAC and y is the serial,
    'the function would be y += x[i] + (i * 2) where i is the index
    'of MAC address element.
    Dim sum As Long = 0
    Dim index As Integer = 1
    For Each ch As Char In mac
        If Char.IsDigit(ch) Then
            sum += sum + Integer.Parse(ch) * (index * 2)
        ElseIf Char.IsLetter(ch) Then
            Select Case ch.ToString.ToUpper
                Case "A"
                    sum += sum + 10 * (index * 2)
                Case "B"
                    sum += sum + 11 * (index * 2)
                Case "C"
                    sum += sum + 12 * (index * 2)
                Case "D"
                    sum += sum + 13 * (index * 2)
                Case "E"
                    sum += sum + 14 * (index * 2)
                Case "F"
                    sum += sum + 15 * (index * 2)
            End Select
        End If

        index += 1
    Next

    Return sum
End Function

This function will give us the unique serial number of each MAC address (not totally unique, but similar to hash function uniqueness).

Generating Activation Key from the Serial Number

The second step is to create the key generator which will generate the activation key from a given serial number. This generator will be placed in a class called KeyGenerator. This class will contain a function which will apply a simple mathematical function on the serial number to get the activation key. In this case, I will use the function f(x) = x2 + 53/x + 113 * (x/4).

Public Class KeyGenerator
    Public Function GenerateKey(ByVal serial As Long) As Long
        Dim x As Long = serial
        Return x * x + 53 / x + 113 * (x / 4)
    End Function
End Class

Back to SecurityManager.vb, we need to add one more function, which is CheckKey(). This function will take the activation key as a parameter, apply the key-generating function on the current MAC address, then compare the two keys to see whether they match or not.

Public Function CheckKey(ByVal key As Long) As Boolean
    Dim x As Long = GetSerial()
    Dim y As Long = x * x + 53 / x + 113 * (x / 4)
    Return y = key
End Function

One important note left: do not place all of these classes in your client's solution! Remember that the key-generating class is only owned by you.

Now you can use these classes to protect your software. You can also use more complicated functions to ensure more security. The key generator may look like this:

gen.JPG

If everything is alright, the user would get the following message.

msg.JPG

For more articles, please visit my blog (in Arabic only).

Happy coding!

License

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

About the Author

Yasser M. Jaffal
Instructor / Trainer Al-Quds University, Jerusalem
Palestinian Territory (Occupied) Palestinian Territory (Occupied)
Member
I am holding a B.Sc in computer science from Al-Quds University, which is the only Arab university in Jerusalem. I ranked first among my colleagues with GPA of 80.2.
I have been working as teaching and research assistant at CS Dpartment, Al-Quds University since April 2006.
Currently, I am preparing to travel to Jordan to continue my graduate studies in Jordan University of Science and Technology (JUST) after being awarded a scholarship from German Academic Exchange Service (DAAD) for two years.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 2memberbehzad20006 May '13 - 5:25 
simple
GeneralMy vote of 1memberbehzad20006 May '13 - 3:58 
no such an inventory!
QuestionModification for .Net 4 [modified]memberJimSharples18 Oct '12 - 21:52 
ManagementClass in the SecurityManager Class GetSerial() Function does not appear to work under .Net 4.
I substituted the following:
Imports System.Net.NetworkInformation
Public Function GetSerial() As Long
 
Dim mac As String = ""
 
Dim nics As NetworkInterface() = NetworkInterface.GetAllNetworkInterfaces()
If nics Is Nothing OrElse nics.Length < 1 Then
  'If no interfaces, set default - whatever hex string you like
  mac = "6CF0490FC2F6"
Else
  For Each adapter As NetworkInterface In nics
    'Avoid Loopback and other adapter types
    If (adapter.OperationalStatus = 1) And (adapter.NetworkInterfaceType = 6) And (adapter.Name = "Local Area Connection") Then
      Dim address As PhysicalAddress = adapter.GetPhysicalAddress()
      mac = address.ToString()
    End If
    If Len(mac) > 0 Then Exit For
  Next
End If
'In case we get no valid adapter (unlikely), then
If Len(mac) = 0 Then mac = "6CF0490FC2F6"
 
... continue with GetSerial function

modified 19 Oct '12 - 20:05.

QuestionThank YoumemberTonyS196829 Aug '12 - 2:58 
This gives me an approach to think about, and I'm sure I can use something like it. Now you've given me something to work from.
QuestionQuestion about Key ActivationmemberMember 86897091 Apr '12 - 20:11 
hi,
i want that the same key will activate product on more than one computer just like in school or lab,how can i do this is there code in c# .
GeneralMy vote of 5memberandy(-RKO)19 Mar '12 - 23:43 
excellent article
GeneralMy vote of 5memberthileep201012 Jan '12 - 21:19 
Hi jaffal. thank you very much your post. I am using ur code in simple billing system. it is very helpful to me. thanks a lot
GeneralMy vote of 5memberZizoovic20 Dec '11 - 2:27 
Free Palestine V from Tunisian people
GeneralMy vote of 5memberOshtri Deka28 Nov '11 - 2:38 
I believe average mark of 3.33 isn't fair. This is nice and simplistic article and should be regarded as such.
After all managed applications are hard to defend.
GeneralMy vote of 5memberManfred R. Bihy9 May '11 - 2:42 
Nice one Yasser!
GeneralCode Changememberenexooone21 Sep '10 - 21:32 
The code generated changes if turn on and off wireless...
but good article providing some useful information
GeneralMy vote of 5memberAwadh Abdullah13 Sep '10 - 23:28 
Good Work, Keep it on bro.
 
You should add some text encreptio to it before storing the key in file
Generalwhere key will be storememberel3ashe216 Feb '10 - 1:18 
nice code but i want to ask
where the code will be store? in registry??
 
i found that code need some implement then may be we can depend on
 
but i think the best way for your application is online key with online database any other ways to store keys will be destroy easy
 

nice try
Generalneed helpmemberdudeman2222 Aug '09 - 4:49 
hi there,
 
I made a simple app on my mac using xcode.
 
How the hell do I copy protect it. I have looked everywhere and here is the closet i've got to the code.
 
I am a noob and kinda know whats going on in the code but how do I implement this into my project. I just need simple protection.
 
Any information will be much appreciated
 
cheers
GeneralMultiple NICs, such as laptopsmembernicorac26 Aug '08 - 1:24 
What about multiple NICs?
I'm thinking about laptops, where you have both Wired and Wireless NICs.
 
There should be a way to use always the wired one, 'cause the wireless could be a PCMCIA card and sometimes could not be inserted.
 

Visit my website for some interesting .NET free tools: http://coolsoft.altervista.org

GeneralHexadecimal numbersmemberTobiasP19 Aug '08 - 3:54 
Both the Parse and TryParse integer methods can be set to accept hexadecimal numbers through the overloads having NumberStyles arguments, so the IsDigit/IsLetter/select case-section can be greatly reduced while giving the same result.
 
Otherwise, I suppose the article can be useful if security is of little concern. It is, as has already been mentioned, easy to crack.
GeneralToo simple for any copy protectionmemberGurliGebis14 Aug '08 - 9:34 
The idea is fine enough.
 
There is one fatal problem with it, since it is quiet easy for somebody to rip open an assembly with Reflector and get the formular for generating the key.
 
A better solution would be to use some sort of encryption for the key.
GeneralRe: Too simple for any copy protection [modified]memberYasser M. Jaffal14 Aug '08 - 9:55 
Hi, I have mentioned in the summary that the compiled code should be protected against reverse engineering before distributing it. But I really don't know if these programs claiming they protect .NET assemblies are good enough... any idea about them?
But you have also to remember that the generator should not be distributed with the software, since it only belongs to the programmer. This means that the assembly will not be available in the first place to be opened using reflection.
 
modified on Thursday, August 14, 2008 11:14 PM

GeneralRe: Too simple for any copy protectionmembermr_ber18 Aug '08 - 20:24 
Although the generator should not be distributed, the validity checking code is a part of the distributed code and it has to calculate the same function. This validity checking code can be used to understand the function.
To solve this issue, some kind of private/public key method should be used. Meaning - you as the developer hold and protect the private key that enables you to generate the activation key from the serial number. The distributed code has only the public key to validate that the provided activation key refers back to the serial number. The problems remain: a - the validity code could be hacked and patched, b - a brute force attack could be used to get the private key.
GeneralRe: Too simple for any copy protectionmemberYasser M. Jaffal19 Aug '08 - 5:00 
I am not saying this is a top security solution - crackers where able to work around Microsft's security so I am sure this would be much easier with my application. But as I said the aim of this demo is to convey a simple idea on beginner's level on the big picture of serial number/activation key-based security.
GeneralRe: Too simple for any copy protectionmembergoogle198219 Jul '11 - 23:47 
Thanks a lot Yasser , It was a very good code , Thanks from a Palestinian In France Smile | :)
GeneralVery UsefullmemberProfiler14 Aug '08 - 6:17 
Thank you! Smile | :)

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 12 Aug 2008
Article Copyright 2008 by Yasser M. Jaffal
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid