Click here to Skip to main content
15,892,059 members
Please Sign up or sign in to vote.
3.33/5 (3 votes)
See more:
Hi,

Well i want to make a protection for my program that it can't be easily copied on other machines.. So far i have come up with getting some Uniques ID's from the machine where the program could run, such as:
1. Getting the MAC address,
2. Getting the Processor ID,
3. Getting the Hard Drive ID and
4. Getting the BIOS Serial number..

Now:
1. By little researching i have seen that having the mac address to identify a PC is a bad idea, mostly because it is easy changed.. So it is out..

2. Next, Processor ID i see as a good idea (by me), and here is the code i use to get it:
string sProcessorID = "";
string sQuery = "SELECT ProcessorId FROM Win32_Processor";
ManagementObjectSearcher oManagementObjectSearcher = new ManagementObjectSearcher(sQuery);
ManagementObjectCollection oCollection = oManagementObjectSearcher.Get();
foreach (ManagementObject oManagementObject in oCollection)
{
    sProcessorID = (string)oManagementObject["ProcessorId"];
}
return (sProcessorID);string sProcessorID = "";
string sQuery = "SELECT ProcessorId FROM Win32_Processor";
ManagementObjectSearcher oManagementObjectSearcher = new ManagementObjectSearcher(sQuery);
ManagementObjectCollection oCollection = oManagementObjectSearcher.Get();
foreach (ManagementObject oManagementObject in oCollection)
{
    sProcessorID = (string)oManagementObject["ProcessorId"];
}
return (sProcessorID);

And so far as i have tested on two machines, it works just fine.. But the problem for this is that i read that not all motherboards will have the serial number populated in the property, and if that does occurs than does someone knows what does it actually returns? (like a string of "Null" or something similar?)

3. Getting the hard drive id is also a good thing, i found a code and here is how the code is:
ststring drive = "C";
ManagementObject dsk = new ManagementObject(@"win32_logicaldisk.deviceid=""" + drive + @":""");
dsk.Get();
string volumeSerial = dsk["VolumeSerialNumber"].ToString();

But the problem here would be, 'does this value is the same after the pc has been formated', and 'is it probably some hard drive not to have its unique id'?

4. Well i don't know if this is actually a good idea, cause when i wanted to read on my PC the Bios ID it says "To Be Filled By O.E.M."...



So here is my idea for protecting my program:
First to read the ProcessorID and HardDriveID (as those two only seems reliable) and write then in my database. Then every time when the programs starts, on load it checks if the string in the database is the same as the current information taken from the current machine.. But for this to make i first have to know what string would it return if there is nothing written as a Processor ID or HardDriveID (like is it '000000' or 'unknown' or something else)...

Or is there even better way to protect my software that i haven't found so far..

I hope i get an answer,
Thank you in forward...
Posted

Pointless exercise.

0) MAC address can be spoofed, and what if there is no active NIC card in the box, or the machine has a number of NIX cards that could be in use at any given time?

1) Processor ID merelu identifies the capabilities of the CPU. No unique.

2) Hard drive ID changes every time the drive is formatted.

3) Not all motherboards have a BIOS serial number that can be retrieved (or is not reported).

If you insist on doing something to prevent unauthorized use, you're just plain better off buying/implementing a 3rd party solution.
 
Share this answer
 
v2
Comments
Xonfused 30-Mar-11 14:04pm    
Thanks for the reply..

Yes, about MAC and HardDrive i am not gonna use them as an ID. But am thinking to use the Processor ID and BIOS ID together as a 'key license' to the program (to give more chances for that key license not to be a null string), but even if both wouldn't return any value, i don't mind, as the PC's that wouldn't return nor for Processor nor for BIOS id, is very low, and my program would have at most 100 customers, so its not that big of a deal if some program can be on other PC that also doesn't return value for both (as they will have the same 'key' string (esample "null"))
(which might not even happen)..
I had a similar requirement for a project and felt equally unsure about it. I ended up using several numbers because of NULLS or empty values just like you mentioned. I use the motherboard serial number, the BIOS serial number, and the UUID. I hash them all together with SHA2 to make it one string and use that string as the unique id code for that computer. So far I haven't run into any problems, but I only have 369 users. Here are the property/collections I'm talking about for the management object:

Property-Collection
SerialNumber-Win32_BaseBoard
SerialNumber-Win32_BIOS
UUID-Win32_ComputerSystemProduct

I concat all those values and hash them with this method to make the one 64 character long string. (sorry it's in vb)

VB
Public Function HashString(ByVal instrString As String) As String
       '   This function will:
       '       - Create a SHA2 hash of the incomming parm and return it.
       '         (Hash will be 64 characters long)

       'Create an encoding object to ensure the encoding standard for the source text
       Dim Ue As New System.Text.UnicodeEncoding()

       'Retrieve a byte array based on the password
       Dim ByteSourceText() As Byte = Ue.GetBytes(Trim(instrString))

       'Instantiate an SHA2 Provider object
       Dim SHA2 As New System.Security.Cryptography.SHA384Managed

       'Compute the hash value from the source
       Dim ByteHash() As Byte = SHA2.ComputeHash(ByteSourceText)

       'And convert it to String format for return
       Dim strSha2 As String = Convert.ToBase64String(ByteHash)

       Return Convert.ToBase64String(ByteHash)

   End Function



Hope this helps.
 
Share this answer
 
Comments
Xonfused 30-Mar-11 13:58pm    
Thanks for the reply. I would have even lower amount of customers..

But i have a little question (if you could answer me):
How do you actually implement the hashed string?
- I was thinking to go to the customer PC, run my own program that would read those "ID's" and insert them in the database of the program that the customer is gonna use.. But with this method i wouldn't need to hash the id's..
So, i am more of curious on why you have actually hashed the id's (i hope i am not asking for too much)..
Kschuler 30-Mar-11 14:10pm    
You don't really NEED to hash it, I did it because it was convenient to know that it was always going to be a 64 character string and so that I could store ONE value instead of several.

As for implementation, I use this in a PC app which calls a web service to hit my companies database. When it performs the call it sends up the hashed code that identifies the machine (as best it can, John pointed out the problems with this method in his solution) and it also sends up a registration code which is just a randomly generate code that was specifically assigned to that user. So when the web service is called it first checks the company database to make sure that the specific machine was assigned to that specific user before performing any tasks. I never store the hashed value that represents the machine on the user's PC, everytime I need to use it I pull it and hash it again. That way no one would be able to manipulate a database entry and get past the check. I hope that makes sense, it's kind of hard to explain.
Xonfused 30-Mar-11 14:16pm    
thanks a lot :)
You can try to use IntelliLock tools,It can solute your problem.
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900