What's a good way to uniquely identify a computer?

WindowsMacosUniqueidentifier

Windows Problem Overview


I'm developing some desktop software for a client to resell. The client wants to restrict the software so that the registration code will be specific to one and only one computer.

Besides using the MAC from the network card, does anyone have any other techniques (that work on both Windows and Mac OS X) for uniquely identifying a computer?

Windows Solutions


Solution 1 - Windows

Another solution is to use a licensing technology with a dongle. This is a small device that plugs into USB or another I/O port on the host, and serves as a unique, physical key to activate the software.

A third solution is to provide a license manager. That is, when the software starts up, it queries a server on the network (either on the customer's LAN or else accessed at your company via the internet) that validates that the customer's usage of the software is legitimate. This is a good solution for "concurrent licenses" so customers can install your software on many hosts, but you license it for simultaneous use on a limited number of hosts. FLEXnet Publisher is an example of a license management solution.

The MAC address of the network card is the solution I used last time I worked for a company that licensed software to run on a specific host.

However, I want to offer a caution: if you do this type of licensing, you have to anticipate that it'll become an ongoing administrative chore to track your customers' licenses. Once you have a few hundred customers, you'll be amazed at how frequently you get phone calls with requests to change keys

> "We upgraded our server to a gigabit > network adapter, and now the license > won't work because the new adapter has > a different MAC address."

Or else the customers may replace their whole machine, and need an updated license to run your software on the new machine. We got these calls practically every day at the company I worked for.

You also need to trust the customer to stop using your software on the old computer (or network adapter) if you give them a new key. If you couldn't trust them to obey the license in the first place, how can you trust that they'll throw away the old key?

If you don't plan how you're going to support this administrative activity, don't license your product in this way. You'll only inconvenience your good customers, who would have cooperated anyway.

Solution 2 - Windows

best way is taking the UUID using C# in Windows

The Best Way To Uniquely Identify A Windows Machine

public string GetUUID()
{
    var procStartInfo = new ProcessStartInfo("cmd", "/c " + "wmic csproduct get UUID")
    {
        RedirectStandardOutput = true,
        UseShellExecute = false,
        CreateNoWindow = true
    };

    var proc = new Process() { StartInfo = procStartInfo };
    proc.Start();

    return proc.StandardOutput.ReadToEnd().Replace("UUID", string.Empty).Trim().ToUpper();
}

Solution 3 - Windows

I'll play devil's advocate here and tell you that something like this probably isn't the best thing to discuss in "public".

With that said, look at what others may have done and possibly improve on (or take a portion of) it. MAC address, like you've said, is possibly okay to use. I've heard that Windows and other programs use hard drive information (serial number) -- according to this site, Windows Activation checks 10 different items and makes them into a unique key.

Solution 4 - Windows

The idea I am toying with is using a few serial numbers or unique id's related to the hardware and hashing them together.

Things that get upgraded: -Memory -MACs (can be spoofed, usb adapters get plugged in, etc.)

Things that don't get upgraded often: -CPU -BIOS -Motherboard

Using WMIC can be a great way to grab some info, I would start by grabbing things that don't change often as the first and preferred choice, I would like to be able to fingerprint at least 2 serial numbers or devices to use for generating a registration key.

wmic cpu get DeviceId /format:value

That will grab the CPU ID, you could run that command for:

1 - CPU (cpu:DeviceID) 2 - Motherboard (baseboard:serialnumber) 3 - BIOS (bios:serialnumber)

if you don't get at least 2 populated values, then grab

4 - Network Adapter - (nic:MACAddress) 5 - RAM - (memphysical:SerialNumber)

Depending on your business logic you can use the first two serial numbers available to create your registration number, and if you always follow the same order then on re-installs the registration number will still work, however if a device changes or a user tries to install on a secondary computer the id's change invalidating the registration number. To reduce the amount of tech support calls the least amount of hardware you fingerprint will give the least amount of headaches and if you try to fingerprint the least likely items to be upgraded that further reduces headaches. My preference is the order above.

You could use a Diffie-Hellman key exchange scheme to have the user generate a private/pulic key pair with their hardware id's as a payload, then pass this information up to a registration server where the registration server would use a public/private key to decrypt the payload and compute the registration key to return back to the end user. I like to use JWT to pass things back and forth witht he public keys included in the payload of the JWT. Hope that helps.

UUID was mentioned above and is a great idea you can get that by using the below command from your windows cmd.exe:

wmic csproduct get UUID /format:value      

Disclaimer these command only work for Windows I think 2000 and above but you would need to verify, they maybe available for systems below 2000 but at that point I really try not to support those devices. Good luck. *Looks like WMI is being deprecated in favor of powershell so to keep this post current here are the power shell commands.

Get-CimInstance -ClassName Win32_Processor | Select SerialNumber

Get-CimInstance -ClassName Win32_BaseBoard | Select SerialNumber

Get-CimInstance -ClassName Win32_Bios | Select SerialNumber

Get-NetAdapter -Physical | Where-Object Status -like Up | Select-Object MacAddress

Get CimInstance -ClassName Win32_PhysicalMemory | Select SerialNumber

The network adapter cmdlet will only check for physical adapters so a virtual adapter couldn't be used and manipulated and I like to use the first adapter that is Up or being used so that a spare NIC can't be swapped around for install reasons.

On Mac:

system_profiler | grep "Serial Number (system)"

On Linux (debian):

sudo dmidecode -t system | grep "Serial Number"

dmidecode and system_profiler has other components it can grab serial numbers from similar to wmic in windows. I don't work on macs so I can't confirm a list of exact specs but creating a list of LCD (least common denominator) the serial numbers for the parts that all three commands can access is put together and groomed to the least likely parts to be upgraded or changed. Then a combination of the top 2-3 numbers hashed can make for a unique machine id that's a bit more robust and allows a cross platform app to be activated even on a device with it's operating system updated.

Solution 5 - Windows

There is no sure way to uniquely identify a computer, if you assume a computer is built with many parts that can be replaced eventually.

Some hardware parts - MAC address, HDD disk serial number, even motherboard serial, etc - are a few good sources of "uniqueness" but as you may know if a client decides to upgrade the part the license depends on... be prepared for some customer support. Also to keep in mind is that some parts can be spoofed (the MAC being one of them).

An online license check is another good way to go - you can manage everything on the server side and even define your own rules for it (how many licenses per client/install, concurrency, etc) but the big thing to note is what happens when connection can't be established?

Solution 6 - Windows

I would just use the MAC address to generate a request key, then require users to register with your client. Your client will have a special application that takes that request key and produces an activation key which the user can then use for activating the software. Once activated, the software works, just works - no occasionally phoning home for verification and such.

That's if it were a real requirement. My first task would be to try and convince the client that this was a bad idea.

The reason is that these schemes practically never prevent your code from being cracked. They do however make the lives of your genuine customers harder. I find it hard to think of any other industry that goes out of its way to annoy its genuine customers with schemes that never achieve their goals (other than government service, of course :-).

If you must do this, I'd just do a token effort to meet the contractual obligation (don't tell your client this however). Taking the MAC address (or a random number if, $DEITY forbid, the computer didn't have a network card) as the request key and using a program to just XOR it with an ASCII string to get the activation key, seems like a workable approach. I would also store both keys since you don't want the software to de-activate if they just change their network card (or even motherboard) - they still see that as the same computer and will not be happy if the software stops working.

Your code's going to be cracked regardless (unless the program is rubbish which I'm sure is not the case) - this method will give your genuine customers an avenue for moving their software to another machine if your client's company becomes unresponsive somehow (drops support, goes out of business, and so on).

The main trouble with all schemes that rely on the uniqueness of a bit of hardware is that the customer may choose to change that bit of hardware:

  • ghosting their disk contents to a larger hard disk makes HD serial numbers change.
  • using CPU serial numbers means upgrading to the latest Intel bigmutha CPU kill your software.
  • using the MAC address means they can't change their NIC.

These can all be fixed by using those values to create a key at install time and only check against that key, not the changed value six months down the track. It means you have to store the request and activation values but upgrades will not require your users to go through the process of re-activating their software. Believe me, they will despise you for having to do that.

Solution 7 - Windows

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography

"MachineGuid” key is generated uniquely during the installation of Windows and it won’t change regardless of any hardware swap (apart from replacing the boot-able hard drive where the OS are installed on). I am not sure about this.

MY SUGGESTION

You can Use that MachineGuid, Hard Disk Serial Number, Mother Board Serial Number and UUID. Together HASH it using SHA 256 or any other HASH function.

UUID - wmic csproduct get UUID

MachineGuid - HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography

Hard Disk Serial Number - wmic diskdrive get serialnumber

BIOS Serial Number - wmic bios get serialnumber

Mother Board Serial Number - wmic baseboard get serialnumber

Solution 8 - Windows

One can create a serial key that the user has to enter once. It should include the user's eMail address (something like [email protected]). This will stop many people from trying to tamper with it or give it to other people. During activation, the software should check against an online db if the serial key exists.

Solution 9 - Windows

How about using MotherBoard unique serial number?

Solution 10 - Windows

Open up Registry and navigate to

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography

Find the key called “MachineGuid” this key is generated uniquely during the installation of Windows and it won’t change regardless of any hardware swap (apart from replacing the boot-able hard drive where the OS are installed on). That means if you want to keep tracking installation per OS this is another alternative. It won’t change unless you do a fresh reinstall of Windows.

Solution 11 - Windows

There used to be a serial number imprinted into the CPU's, as far as I have seen though; this information (PSN, Pentium Serial Number) has been deprecated. The information may possibly still exist, but at least in the P3 world it was gone. Also, I think the obvious choice of MAC address on the NIC for the main interface used for the host should be considered as a real possibility. Unless your client is not expecting ethernet interfaces to be present on the hosts that they sell to.

Solution 12 - Windows

You might consider a third-party licensing utility which will more likely get this "right" and also provide you (or your client) with additional options should requirements change (and don't they always?). I'd mention some specific ones by name, but I'm really not intimately familiar them.

Solution 13 - Windows

I have some experience on this. In my solution we issue service key when we sell the product to the client.

At the time client install the application it generate a key by reading the motherboard serial of the client machine. Client is supposed to email the service key and the key generated at the installation to our organization to activate the product.

We maintain an admin application at the organization at issue activation keys. We offer only one activation key for key for a particular service key.

We sold number of copies and it runs without an issue. But then we found out some computers that does not provide a motherboard serial number. Those machines return null value as the motherboard serial number. still we trying to fix this issue.

Solution 14 - Windows

Or you could simply have no activiation code and ensure you have audit rights written into the EULA and exercise your right to audit from time to time.

Works wonders for Oracle.

Solution 15 - Windows

how about hashing anything that has a burned-in SN, harddrive, proc, ram, etc... this hash will remain with the computer until it has it's parts replaced.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPaul LefebvreView Question on Stackoverflow
Solution 1 - WindowsBill KarwinView Answer on Stackoverflow
Solution 2 - WindowsDilan WickramarathnaView Answer on Stackoverflow
Solution 3 - WindowsNicholas HeadView Answer on Stackoverflow
Solution 4 - WindowsHarry ChilinguerianView Answer on Stackoverflow
Solution 5 - WindowsJ.C. InacioView Answer on Stackoverflow
Solution 6 - WindowspaxdiabloView Answer on Stackoverflow
Solution 7 - WindowsvarshanbpView Answer on Stackoverflow
Solution 8 - WindowstmightyView Answer on Stackoverflow
Solution 9 - Windowsuser2912991View Answer on Stackoverflow
Solution 10 - WindowsTelson AlvaView Answer on Stackoverflow
Solution 11 - WindowsSurootView Answer on Stackoverflow
Solution 12 - WindowsÐаnView Answer on Stackoverflow
Solution 13 - WindowsgihanView Answer on Stackoverflow
Solution 14 - WindowstroyView Answer on Stackoverflow
Solution 15 - WindowsnoneView Answer on Stackoverflow