views:

5383

answers:

12

I need to write a function that generates an id that is unique for a given machine running a Windows OS.

Currently, I'm using WMI to query various hardware parameters and concatenate them together and hash them to derive the unique id. My question is, what are the suggested parameters I should use? Currently, I'm using a combination of bios\cpu\disk data to generate the unique id. And am using the first result if multiple results are there for each metric.

However, I ran into an issue where a machine that dual boots into 2 different Windows OS generates different site codes on each OS, which should ideally not happen.

For reference, these are the metrics I'm currently using:

Win32_Processor:UniqueID,ProcessorID,Name,Manufacturer,MaxClockSpeed
Win32_BIOS:Manufacturer
Win32_BIOS:SMBIOSBIOSVersion,IdentificationCode,SerialNumber,ReleaseDate,Version
Win32_DiskDrive:Model, Manufacturer, Signature, TotalHeads
Win32_BaseBoard:Model, Manufacturer, Name, SerialNumber
Win32_VideoController:DriverVersion, Name

And if multiple values are there for each

A: 

You should look into using the MAC address on the network card (if it exists). Those are usually unique but can be fabricated. I've used software that generates its license file based on your network adapter MAC address, so it's considered a fairly reliable way to distinguish between computers.

Kyle Cronin
No, they aren't. A lot of manufacturer allows you to change them. This is very helpfull when working with clusters because some of the vendors gives you all the computer with the same MAC address (we ran into this issue a few years ago).
gizmo
I stand corrected.
Kyle Cronin
+1  A: 

What about just using the UniqeID of the processor?

gizmo
Isn't that a depreciated property these days?
Jakobud
A: 

look up CPUID for one option. There might be some issues with multi-CPU systems

BCS
+1  A: 

Why not use the MAC address of your network card?

bmatthews68
He didn't mention that all the comuter have a network card.
gizmo
Mac address can be spoofed
PintSizedCat
A: 

Maybe cheating a little, but the MAC Address of a machines Ethernet adapter rarely changes without the motherboard changing these days.

A lot of manufacturer allows you to change them. This is very helpfull when working with clusters because some of the vendors gives you all the computer with the same MAC address (we ran into this issue a few years ago).
gizmo
A: 

I hate to be the guy who says, "you're just doing it wrong" (I always hate that guy ;) but...

Does it have to be repeatably generated for the unique machine? Could you just assign the identifier or do a public/private key? Maybe if you could generate and store the value, you could access it from both OS installs on the same disk?

You've probably explored these options and they doesn't work for you, but if not, it's something to consider.

If it's not a matter of user trust, you could just use MAC addresses.

Sam Hoice
MAC addresses won't work if the machine doesn't have a network card.
brian
@Brian - do you really need a unique value to identify a computer that doesn't have a network card? Seems a pretty safe bet the machine has a card.
romandas
A: 

Can you pull some kind of manufacturer serial number or service tag?

Our shop is a Dell shop, so we use the service tag which is unique to each machine to identify them. I know it can be queried from the BIOS, at least in Linux, but I don't know offhand how to do it in Windows.

Christopher Cashell
+4  A: 

Parse the SMBIOS yourself and hash it to an arbitrary length. See the PDF specification for all SMBIOS structures available.

To query the SMBIOS info from Windows you could use EnumSystemFirmwareEntries and GetSystemFirmwareTable.

IIRC, the "unique id" from the CPUID instruction is deprecated from P3 and newer.

Jonas Gulle
A: 

Consider using a Global Unique Identifier (GUID)

Also see here for some Pros and Cons

Markus Lux
+1  A: 

In my program I first check for Terminal Server and use the WTSClientHardwareId else the mac address of the local pc should be adequate.

If you really want to use the list of properties you provided leave out things like name and DriverVersion,Clockspeed,etc since it's possibly OS dependent. Try outputting the same info on both operating systems and leave out that which differs between.

AngelBlaZe
+4  A: 

I too have the same issue. I tried the WTSClientHardwareId suggestion by AngelBlaZe using the following code:

DWORD dwId = 0, dwSize = 0;

WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION,
                           WTSClientHardwareId, &dwId, &dwSize);

This produced good results on XP, but unfortunately produced a different value each time it was run under Vista!

I've come accross the following registry key which appears to be unique on a per machine basis:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography

under this is a value named "MachineGuid"

Having queried it on several XP and Vista boxes, it looks like it would serve the purpose quite nicely. Trouble is, I've got no idea how reliable this would be as I don't know how it was generated and how subject to change it is? Googling has produced miminal answers. Anyone care to shed any more light?

I would like to know if this has worked for you, and can I take it up for generating license keys based on this??
Xinxua
This is great! The only problem is that the user can change the GUID, so you can't depend on it being immutable. But if it's a) always present on windows machines and b) unique, that's a great start.Maybe combine this with one of the others (CPUID) to be more robust. Nice find, Angus.
Rocketmonkeys
+7  A: 

I had the same problem and after a little research I decided the best would be to read HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography, as Agnus suggested. It is generated during OS installation and won't change unless you make another fresh OS install. Depending on the OS version it may contain the network adapter MAC address embedded (plus some other numbers, including random), or a pseudorandom number, the later for newer OS versions (after XP SP2, I believe, but not sure). If it's a pseudorandom theoretically it can be forged - if two machines have the same initial state, including real time clock. In practice, this will be rare, but be aware if you expect it to be a base for security that can be attacked by hardcore hackers.

Of course a registry entry can also be easily changed by anyone to forge a machine GUID, but what I found is that this would disrupt normal operation of so many components of Windows that in most cases no regular user would do it (again, watch out for hardcore hackers).

Fabio Ceconello
Is this feasible? I mean that depending on this key alone is sufficient for a robust licensing system??
Xinxua
Not at all. In my case, for instance, I use it for audit purposes only. Unfortunately there's no reliable DRM infrastructure in common PCs. A robust licensing system, as you mentioned, would need to make use of external (USB dongles) or non-standard (CPUID) sources for a unique number.
Fabio Ceconello