Click here to Skip to main content
11,487,401 members (72,522 online)
Click here to Skip to main content

Generating Unique Key (Finger Print) for a Computer for Licensing Purposes

, 24 Jan 2011 CPOL 161.4K 263
Rate this:
Please Sign up or sign in to vote.
Generating Unique Key(Finger Print) for a Computer for Licensing Purposes

Introduction

For licensing purposes, according to me, the best and secure way is to generate a unique key for the client's machine and provide a corresponding license key for that key. For this purpose, you can take help of the unique id of the client's computer motherboard, BIOS and processor. When you get these IDs, you can generate any key of your preferable format.

Year ago, I found a very handy and useful code in C# by searching the Internet to get these IDs. And it's serving me perfectly so far. Thanks to the original author of the code.

I added some additional code to generate a 128 bit key of a machine. The output is a nice looking key in hexadecimal format (eg. 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9).

Suggestions

I have a few suggestions in this regard:

  • Generate a key from only the Motherboard, Processor and BIOS since the user normally doesn't change these parts.
  • Don't use MAC ID, Graphics Card ID AND Disk ID since it's very common to change these devices.
  • It takes significant time to get IDs of devices. So make the finger print generating function static and save it in a static variable so that it generates the key only once in the whole application.

The Code

Here is the class. The code in the region "Original Device ID Getting Code" is from the original author.

using System;
using System.Management;
using System.Security.Cryptography;
using System.Security;
using System.Collections;
using System.Text;
namespace Security
{
    /// <summary>
    /// Generates a 16 byte Unique Identification code of a computer
    /// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9
    /// </summary>
    public class FingerPrint  
    {
        private static string fingerPrint = string.Empty;
        public static string Value()
        {
            if (string.IsNullOrEmpty(fingerPrint))
            {
                fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " + 
			biosId() + "\nBASE >> " + baseId()
                            //+"\nDISK >> "+ diskId() + "\nVIDEO >> " + 
			videoId() +"\nMAC >> "+ macId()
                                     );
            }
            return fingerPrint;
        }
        private static string GetHash(string s)
        {
            MD5 sec = new MD5CryptoServiceProvider();
            ASCIIEncoding enc = new ASCIIEncoding();
            byte[] bt = enc.GetBytes(s);
            return GetHexString(sec.ComputeHash(bt));
        }
        private static string GetHexString(byte[] bt)
        {
            string s = string.Empty;
            for (int i = 0; i < bt.Length; i++)
            {
                byte b = bt[i];
                int n, n1, n2;
                n = (int)b;
                n1 = n & 15;
                n2 = (n >> 4) & 15;
                if (n2 > 9)
                    s += ((char)(n2 - 10 + (int)'A')).ToString();
                else
                    s += n2.ToString();
                if (n1 > 9)
                    s += ((char)(n1 - 10 + (int)'A')).ToString();
                else
                    s += n1.ToString();
                if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-";
            }
            return s;
        }
        #region Original Device ID Getting Code
        //Return a hardware identifier
        private static string identifier
		(string wmiClass, string wmiProperty, string wmiMustBeTrue)
        {
            string result = "";
            System.Management.ManagementClass mc = 
		new System.Management.ManagementClass(wmiClass);
            System.Management.ManagementObjectCollection moc = mc.GetInstances();
            foreach (System.Management.ManagementObject mo in moc)
            {
                if (mo[wmiMustBeTrue].ToString() == "True")
                {
                    //Only get the first one
                    if (result == "")
                    {
                        try
                        {
                            result = mo[wmiProperty].ToString();
                            break;
                        }
                        catch
                        {
                        }
                    }
                }
            }
            return result;
        }
        //Return a hardware identifier
        private static string identifier(string wmiClass, string wmiProperty)
        {
            string result = "";
            System.Management.ManagementClass mc = 
		new System.Management.ManagementClass(wmiClass);
            System.Management.ManagementObjectCollection moc = mc.GetInstances();
            foreach (System.Management.ManagementObject mo in moc)
            {
                //Only get the first one
                if (result == "")
                {
                    try
                    {
                        result = mo[wmiProperty].ToString();
                        break;
                    }
                    catch
                    {
                    }
                }
            }
            return result;
        }
        private static string cpuId()
        {
            //Uses first CPU identifier available in order of preference
            //Don't get all identifiers, as it is very time consuming
            string retVal = identifier("Win32_Processor", "UniqueId");
            if (retVal == "") //If no UniqueID, use ProcessorID
            {
                retVal = identifier("Win32_Processor", "ProcessorId");
                if (retVal == "") //If no ProcessorId, use Name
                {
                    retVal = identifier("Win32_Processor", "Name");
                    if (retVal == "") //If no Name, use Manufacturer
                    {
                        retVal = identifier("Win32_Processor", "Manufacturer");
                    }
                    //Add clock speed for extra security
                    retVal += identifier("Win32_Processor", "MaxClockSpeed");
                }
            }
            return retVal;
        }
        //BIOS Identifier
        private static string biosId()
        {
            return identifier("Win32_BIOS", "Manufacturer")
            + identifier("Win32_BIOS", "SMBIOSBIOSVersion")
            + identifier("Win32_BIOS", "IdentificationCode")
            + identifier("Win32_BIOS", "SerialNumber")
            + identifier("Win32_BIOS", "ReleaseDate")
            + identifier("Win32_BIOS", "Version");
        }
        //Main physical hard drive ID
        private static string diskId()
        {
            return identifier("Win32_DiskDrive", "Model")
            + identifier("Win32_DiskDrive", "Manufacturer")
            + identifier("Win32_DiskDrive", "Signature")
            + identifier("Win32_DiskDrive", "TotalHeads");
        }
        //Motherboard ID
        private static string baseId()
        {
            return identifier("Win32_BaseBoard", "Model")
            + identifier("Win32_BaseBoard", "Manufacturer")
            + identifier("Win32_BaseBoard", "Name")
            + identifier("Win32_BaseBoard", "SerialNumber");
        }
        //Primary video controller ID
        private static string videoId()
        {
            return identifier("Win32_VideoController", "DriverVersion")
            + identifier("Win32_VideoController", "Name");
        }
        //First enabled network card ID
        private static string macId()
        {
            return identifier("Win32_NetworkAdapterConfiguration", 
				"MACAddress", "IPEnabled");
        }
        #endregion
    }
}

Upcoming Code

Later I'll show how I generated the license key from the unique machine key. The license key contains a lot of information like the Product Name, License Start Date, End Date and the Key.

Keep eyes on my blog (sowkot.blogspot.com).

History

  • 19th August, 2008: Initial post

My Other Articles

License

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

Share

About the Author

Sowkot Osman
Software Developer (Senior)
Australia Australia
-7 years of extensive experience in devloping both desktop and web applications in C#.NET, VB.NET and ASP.NET, ASP.NET MVC 3.0/4.0
-5 years of experience in developing web applications in J2EE, Free Marker, JSP, Spring MVC, Spring Webflow.
-Expertise in Software Architecture and Framework design.
Blog: http://sowkot.blogspot.com


Comments and Discussions

 
BugProcessor no more unique now. BIOS too. Pin
qakmak25-Apr-15 20:53
memberqakmak25-Apr-15 20:53 
GeneralMy vote of 5 Pin
Guy__Levin13-Apr-15 7:08
memberGuy__Levin13-Apr-15 7:08 
Bugwin 8 problem Pin
umut_sayar23-Mar-15 23:48
memberumut_sayar23-Mar-15 23:48 
GeneralRe: win 8 problem Pin
Member 1019765031-Mar-15 4:02
memberMember 1019765031-Mar-15 4:02 
GeneralRe: win 8 problem Pin
qakmak21-Apr-15 17:36
memberqakmak21-Apr-15 17:36 
BugProblem with disk fingerprint and USB drives Pin
Paul 1234510-Mar-15 0:56
memberPaul 1234510-Mar-15 0:56 
GeneralRe: Problem with disk fingerprint and USB drives Pin
Member 1087520222-Mar-15 6:17
memberMember 1087520222-Mar-15 6:17 
GeneralRe: Problem with disk fingerprint and USB drives Pin
Member 1019765031-Mar-15 4:20
memberMember 1019765031-Mar-15 4:20 
Questionthe other article Pin
vipz0071-Oct-14 17:52
membervipz0071-Oct-14 17:52 
QuestionIs ther any chance of change in key after format even 0.01%? Pin
Krishna Kapadia12-Aug-14 10:49
memberKrishna Kapadia12-Aug-14 10:49 
QuestionWhen will you be explaining on how to create license keys Pin
mukeshgmail4-Jun-14 8:21
membermukeshgmail4-Jun-14 8:21 
SuggestionMessage Automatically Removed Pin
15-May-14 8:06
memberkamleshgs15-May-14 8:06 
QuestionThanks! Pin
basarTurgut13-Jan-14 2:45
memberbasarTurgut13-Jan-14 2:45 
QuestionCool! Pin
diogopessoa29-Nov-13 6:05
memberdiogopessoa29-Nov-13 6:05 
GeneralMy vote of 2 Pin
bobfox5-Nov-13 18:39
professionalbobfox5-Nov-13 18:39 
BugWhat happen on cloning the harddisk? Pin
Xhek30-Oct-13 10:53
memberXhek30-Oct-13 10:53 
GeneralMy vote of 5 Pin
URVISH_SUTHAR128-Oct-13 4:25
memberURVISH_SUTHAR128-Oct-13 4:25 
SuggestionGreat article but i prefer Usb Dongle Pin
iProg72-Sep-13 9:00
memberiProg72-Sep-13 9:00 
GeneralRe: Great article but i prefer Usb Dongle Pin
adriancs25-Sep-13 17:00
mvpadriancs25-Sep-13 17:00 
QuestionREG: Reversing the hash string Pin
Member 83233541-Jun-13 5:26
memberMember 83233541-Jun-13 5:26 
AnswerRe: REG: Reversing the hash string Pin
adriancs25-Sep-13 17:06
mvpadriancs25-Sep-13 17:06 
GeneralMy vote of 5 Pin
cava4des4-Feb-13 19:40
membercava4des4-Feb-13 19:40 
Question[My vote of 1] 99% of this was done by the "other" guy Pin
Jose A Pascoa2-Feb-13 22:47
memberJose A Pascoa2-Feb-13 22:47 
QuestionWould love to see the final part where reverse the hex string back Pin
earthit23-Jan-13 5:54
memberearthit23-Jan-13 5:54 
GeneralRe: Would love to see the final part where reverse the hex string back Pin
pchinery12-Jun-13 6:40
memberpchinery12-Jun-13 6:40 
Questionjust my 0.01 cents :) Pin
Jayson Ragasa5-Dec-12 17:15
memberJayson Ragasa5-Dec-12 17:15 
Answerhow about this? Pin
adriancs25-Sep-13 17:11
mvpadriancs25-Sep-13 17:11 
QuestionDon't forget to add your Reference! Haha Pin
androgenic_human30-Nov-12 17:51
memberandrogenic_human30-Nov-12 17:51 
QuestionMono Support? Pin
Eddie Y Chen2-Nov-12 22:39
memberEddie Y Chen2-Nov-12 22:39 
Questionget back original data Pin
Krishna Kapadia28-Oct-12 21:16
memberKrishna Kapadia28-Oct-12 21:16 
GeneralNot so easy Pin
numo25-Jun-12 4:23
membernumo25-Jun-12 4:23 
QuestionHack the key Pin
nitin-aem16-Jun-12 2:42
membernitin-aem16-Jun-12 2:42 
AnswerRe: Hack the key Pin
softwaretry10-Jul-12 3:35
membersoftwaretry10-Jul-12 3:35 
GeneralRe: Hack the key Pin
nitin-aem10-Jul-12 19:20
membernitin-aem10-Jul-12 19:20 
GeneralRe: Hack the key Pin
vishalgpt29-Jul-12 23:40
membervishalgpt29-Jul-12 23:40 
GeneralRe: Hack the key Pin
WestieBoy24-Feb-13 18:44
memberWestieBoy24-Feb-13 18:44 
GeneralRe: Hack the key Pin
vishalgpt12-May-13 22:44
membervishalgpt12-May-13 22:44 
AnswerRe: Hack the key Pin
adriancs25-Sep-13 17:15
mvpadriancs25-Sep-13 17:15 
Questionc++ unique key Pin
syasaketi19-Feb-12 19:49
membersyasaketi19-Feb-12 19:49 
Questiongreat work Pin
Alex C. Duma14-Feb-12 4:38
memberAlex C. Duma14-Feb-12 4:38 
Questiongenerate numbers Pin
Cool Smith12-Feb-12 5:10
memberCool Smith12-Feb-12 5:10 
QuestionNeed descriptive explanation Pin
Sunasara Imdadhusen16-Nov-11 23:10
memberSunasara Imdadhusen16-Nov-11 23:10 
Generalhow to validate the serial number Pin
Jenhuohuo4-May-11 5:05
memberJenhuohuo4-May-11 5:05 
GeneralI have to disagree... Pin
Daniel Desormeaux26-Jan-11 12:24
memberDaniel Desormeaux26-Jan-11 12:24 
GeneralRe: I have to disagree... Pin
tlhintoq31-Jan-11 9:50
membertlhintoq31-Jan-11 9:50 
GeneralRe: I have to disagree... Pin
Daniel Desormeaux31-Jan-11 13:23
memberDaniel Desormeaux31-Jan-11 13:23 
GeneralMy vote of 5 Pin
kdgupta8725-Jan-11 1:27
memberkdgupta8725-Jan-11 1:27 
GeneralMy vote of 2 Pin
Pavel Vladov25-Jan-11 0:02
memberPavel Vladov25-Jan-11 0:02 
GeneralMy vote of 4 Pin
Klaus Luedenscheidt24-Jan-11 20:04
memberKlaus Luedenscheidt24-Jan-11 20:04 
Generalits good Pin
Pranay Rana24-Jan-11 19:49
memberPranay Rana24-Jan-11 19:49 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150520.1 | Last Updated 24 Jan 2011
Article Copyright 2011 by Sowkot Osman
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid