Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

C# Tutorial - Generating a unique hardware ID

hwid hardware id identification license serial key

  • Please log in to reply
2 replies to this topic

#1 DeadLine

DeadLine

    CC Regular

  • Member
  • PipPipPip
  • 41 posts
  • Location:Belgium
  • Programming Language:Java, C#, PHP, (Visual) Basic, JavaScript, PL/SQL, Delphi/Object Pascal, Visual Basic .NET, Pascal, VBScript
  • Learning:C++, JavaScript, Delphi/Object Pascal, Pascal

Posted 31 May 2014 - 01:33 PM

Introduction:

 

In this tutorial, you will learn how to generate a unique hardware ID.

You might be wondering why you would want to generate a unique hardware ID. Well, you can do a lot with them:

  • You can use them for licensing purposes
  • Statistical purposes
  • ...

So, what exactly is a hardware ID (HWID) ?:

 

A hardware ID is a unique identifier generated from the serial numbers present in computer hardware. A hardware ID is not universal,  meaning that developers will usually use different methods to compose a hardware ID. In this tutorial I'll show you my preferred method of generating a hardware ID.

 

Sources:

 

(We will be using Sowkot Osman's code, but a modified version to improve performance)

 

Tutorial:

 

To generate a HWID, I generally grab the serials of CPU, motherboard, graphics card, BIOS, NIC and the disk. Then, I generate a MD5 hash using those variables and convert them to a hexadecimal value.

You will need the following in order to complete this tutorial:

  • Visual Studio or any other .NET (C#) IDE
  • A CPU
  • A motherboard
  • A graphics card
  • BIOS
  • a NIC
  • A hard drive

 

Step 1:

 

The first we will need to do is create a new console application or use an existing project:

 

Ir5UpYv.png

 

Step 2:

 

Now, it's time to add a reference to 'System.Management' to your project. You will need this reference in order to grab the serials of the computers hardware. You can do this by right clicking the references in the Solution Explorer and selecting 'Add reference...':

E8Ckrp5.pngNlleQ6c.png

Step 3:

 

We will be using the following references in the 'Using' list:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;

The main method will look like this:

        static void Main()
        {
            Console.Write("Your HWID: ");
            Console.WriteLine(Value());
            Console.ReadLine();
        }

We will use the following code to generate a MD5 hash of our hardware serials:

        private static string GetHash(string s)
        {
            //Initialize a new MD5 Crypto Service Provider in order to generate a hash
            MD5 sec = new MD5CryptoServiceProvider();
            //Grab the bytes of the variable 's'
            byte[] bt = Encoding.ASCII.GetBytes(s);
            //Grab the Hexadecimal value of the MD5 hash
            return GetHexString(sec.ComputeHash(bt));
        }

In order to generate the hexadecimal string of the hash, you will need to add the following code:

        private static string GetHexString(IList<byte> bt)
        {
            string s = string.Empty;
            for (int i = 0; i < bt.Count; i++)
            {
                byte b = bt[i];
                int n = b;
                int n1 = n & 15;
                int n2 = (n >> 4) & 15;
                if (n2 > 9)
                    s += ((char)(n2 - 10 + 'A')).ToString(CultureInfo.InvariantCulture);
                else
                    s += n2.ToString(CultureInfo.InvariantCulture);
                if (n1 > 9)
                    s += ((char)(n1 - 10 + 'A')).ToString(CultureInfo.InvariantCulture);
                else
                    s += n1.ToString(CultureInfo.InvariantCulture);
                if ((i + 1) != bt.Count && (i + 1) % 2 == 0) s += "-";
            }
            return s;
        }

The code above is used to generate the hexadecimal value of a string. For more information on Hexadecimal, please click here.

The code above will also add a '-' after every 4th character.

 

If you've done everything right, you should have a little error in your code. The method 'Value()' does not exist. This method will be used to grab the final hardware ID. Let's add it:

        private static string _fingerPrint = string.Empty;
        private static string Value()
        {
            //You don't need to generate the HWID again if it has already been generated. This is better for performance
            //Also, your HWID generally doesn't change when your computer is turned on but it can happen.
            //It's up to you if you want to keep generating a HWID or not if the function is called.
            if (string.IsNullOrEmpty(_fingerPrint))
            {
                _fingerPrint = GetHash("CPU >> " + CpuId() + "\nBIOS >> " + BiosId() + "\nBASE >> " + BaseId() + "\nDISK >> " + DiskId() + "\nVIDEO >> " + VideoId() + "\nMAC >> " + MacId());
            }
            return _fingerPrint;
        }

The code to get the hardware serials will be reused by different methods so first, we will create a new method for the code that's actually going to grab the required hardware serials:

        //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.ManagementBaseObject mo in moc)
            {
                if (mo[wmiMustBeTrue].ToString() != "True") continue;
                //Only get the first one
                if (result != "") continue;
                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.ManagementBaseObject mo in moc)
            {
                //Only get the first one
                if (result != "") continue;
                try
                {
                    result = mo[wmiProperty].ToString();
                    break;
                }
                catch
                {
                }
            }
            return result;
        }

In order to grab the CPU ID, you will need to use the 'Identifier' code above with a couple of variables.

The code below will grab the UniqueID field from the processor but you don't need to grab all the different CPU ID's since this is very time consuming and some of them can fail on certain machines. That's why you need to add several more checks to actually get the appropriate processor id for the processor:

        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 != "") return retVal;
            retVal = Identifier("Win32_Processor", "ProcessorId");
            if (retVal != "") return retVal;
            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;
        }

For the BIOS ID, we will grab several variables such as the manufacturer, version, identification code, serial number etc.:

        //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");
        }

We could just get the serialnumber but using multiple variables will decrease the chances of machines having the same final HWID.

 

In order to get the hard drive information, you will need to use the following code:

        //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");
        } 

Again, we grab multiple variables in order to decrease the chances of machines having the same final HWID.

 

For the motherboard ID, we will grab the model, manufacturer, name and serialnumber.

This is the code to grab the motherboard information:

        //Motherboard ID
        private static string BaseId()
        {
            return Identifier("Win32_BaseBoard", "Model") + Identifier("Win32_BaseBoard", "Manufacturer") + Identifier("Win32_BaseBoard", "Name") + Identifier("Win32_BaseBoard", "SerialNumber");
        }

Right now, we still need the graphics card and NIC information. We will only get the driver version and name of the video card:

        //Primary video controller ID
        private static string VideoId()
        {
            return Identifier("Win32_VideoController", "DriverVersion") + Identifier("Win32_VideoController", "Name");
        }

We only want to grab the NIC mac address when the variable IPENABLED is true:

        //First enabled network card ID
        private static string MacId()
        {
            return Identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
        }

Step 4:

 

Now it's time to actually run your program. Press F5 to run your application and try it out !

u5OrcVs.png

Attached Files

  • Attached File  HWID.zip   25.06KB   3250 downloads

  • 3

#2 sam_coder

sam_coder

    CC Addict

  • Senior Member
  • PipPipPipPipPip
  • 380 posts

Posted 02 June 2014 - 08:53 AM

Just taking a moment to show my appreciation for a tutorial, beautifully laid out and on a pretty original topic.  I feel as though I've learned something. =)

Good work!


  • 0

#3 DavidThomasAllen

DavidThomasAllen

    CC Lurker

  • Just Joined
  • Pip
  • 1 posts

Posted 12 June 2015 - 01:01 AM

Signed up to say Thanks for this

 

I am new to coding and your tutorial helped me get this right

 

Thanks again


  • 0





Also tagged with one or more of these keywords: hwid, hardware, id, identification, license, serial, key