Search Here

Custom Search

Tuesday, August 19, 2008

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


Download the complete source code.


Introduction

For licensing purpose according to me the best way and secure way is to generate an unique key for client's machine and providing a corresponding license key for that key. For this purpose you can take help of the unique id of client's computer's motherboard, BIOS and processor's. 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 net to get these IDs. And its 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 few suggestions on this regard.

*) Generate key from only Motherboard, Processor and BIOS. Since user normally doesn't chagne these parts.

*) Don't use MAC ID, Graphics Card ID AND Disk ID. Since its very common to change these devices.

*) It takes significant time to get IDs of devices. So make the finger print generating fucntion static and save it in a static variable so that it generates the key only for one time 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 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 many information like the Product Name, License Start Date, End Date and the Key.


Download the complete source code.

26 comments:

cocis said...

Sowkot,

Great way to find the serial numbers, thanks for the code
I was looking the way to read some serial numbers, the hard drive serail number, I find out that the HD serial number can be clone.

Very cool

Sowkot said...

Thanks for your comment, Cocis.

Raymond said...

Nice code! very usefull.. can you show the rest (how to get the licence key etc)?

jarp said...

Really fantastic!

When you will have the upcoming code?

Unknown said...

hi
i am need to Decode FingerPrint.Value() result and get bios information , cpu information and etc.
please help me.
thanks.

Unknown said...

how to achieve the same using asp.net. I want the client machines code using asp.net. I tried out the same code. But it is getting me the hosted server machines hardware id rather than Client machine Id.

Please suggest.

StormySeaSailor said...

I already saw the original code but your changes are great !
It's true that some hardware parts change a lot ... also with the same hardware the VideoId() was giving me different values depending on how the code was called (video drivers would change ?).

Note: the hash makes the serial look more professional however a hash is not unique. The chances are damn small but theoretically two different machines could generate the same key ... anyway I'm still going with it ;-)

Shohag_ifas said...

hi, brother thanks for nice sharing...

but my coding language is vb6 so, it's no use to me.. but i need this.. to.. much..

can you make it a dll file what can be access/called from vb 6?

please brother leave a reply asap at altufaltu.sb@gmail.com

Seguridad Informática said...

I found the concept responding superbly to my needs.

I do programming in C and some C++ and would appreciate any help you provide for providing converting information to C or C++ for Linux and for Windows.

Seguridad Informática said...

I found the concept responding superbly to my needs.

I do programming in C and some C++ and would appreciate any help you provide for providing converting information to C or C++ for Linux and for Windows.

Unknown said...

How to get disk identification number in case of GPT partition style. Since signature becomes NULL for this case.

Cool Brezze said...

thanks but i need equivalent in vb6

Cool Brezze said...

merci pour ta solution mais je developpe en vb6 stp u pourai m'envoyer l'equivalent en vb6 avec un peu plus d'explication sur comment l'utiliser

Morpheus said...

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

So when are you going to do this I would like to see it.

Anonymous said...

Hi , all code is nice...
but what is the "Management class" , i receive these errors==>
"The type or namespace name 'ManagementClass' does not exist in the namespace 'System.Management' "

Zobayer Hasan said...

@Tushar Jagdale
You need to manually add System.Management as a Reference. Just "using" is not enough.

cgb1776 said...

This code is great! Could really use the info on how to create the license key.

Unknown said...

Absolutely fantastic. When will you be explaining on how to create license keys.

Unknown said...

Thanks a lot, you´ve done my life easier

Anonymous said...

Hello Sir

I Want to make a license for my windows application so that it can expire after 3 months , how it can be possible like antivirus softwares OR IDM Software.

Once my project(software) is installed.i need to track the date when it is installed then from that date after 3 Months.should display the messages 3 Months Trial version software expires.
Or it will stop the software so that i can protect my software.

I am new , and this is my first application, if possible then please provide me code or full description

How to implement this part in Windows application in C#.net

Thanks

Unknown said...

Thanks For your code, but its not worked for me on hosted environment using ASP.Net, its throwing error like "Access denied", but its worked for my local machine, please how can I achieve it on hosted network.

Mati said...

hello, i don't understand the GetHexString function code ...

"
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 += "-";
"

Rob said...

Hi there,
where is the solution you promised here:
"Upcoming Code

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

amlifier said...

Please Post Visual Studio Form Application Project for this

Unknown said...

Hi Sowkot ,
How to generate license Key by HDDSerial and ProcessorID of Computer ?
Thanks you !

Gilman12 said...

ERROR :"The program does not contain any static 'Main' method suitable for an entry point".
Where is the main in this code??