11

For a requirement to generate per-PC license keys, I need some code which will return a stable and (near) unique key on any PC. It doesn't have to be guaranteed unique, but close. It does need to be reasonably stable though, so that a given PC always generates the same result unless the hardware is substantially changed.

This is for a Windows application, using wxWidgets but a Win32 or other option is fine.

I was thinking about MAC address but what about laptops which can routinely disable the network card in power-saving mode? I came across GetCurrentHwProfile but it doesn't quite look like what I want?

Mr. Boy
  • 60,845
  • 93
  • 320
  • 589

7 Answers7

6

One idea I had a while back for this is to use CryptProtectData as a way to identify a machine. Behind-the-scenes in that API, Microsoft has done what you're looking for. I never tested it though and I'm curious if it's actually viable.

Basically you would encode a constant magic value with CryptProtectData with CRYPTPROTECT_LOCAL_MACHINE, and the result is your machine ID.

tenfour
  • 36,141
  • 15
  • 83
  • 142
  • That's pretty interesting. We might try it, if we do I'll post back. – Mr. Boy Sep 03 '10 at 14:09
  • 3
    I've tested this and it does not appear to work. Encrypting the same string repeatedly yields different results each time. Providing a constant 'pOptionalEntropy' does not help. – TC. Feb 28 '13 at 13:15
2

I would just go with the MAC address method; when the wireless / LAN cards are turned off they still show up in Network Connections. You should therefore still be able to get the MAC.

Consider this: Any time you'd be able to contact your webserver or whatever you're cataloging these IDs with, the user is going to have to have some form of network card available.

Oh, and you might be able to use CPU serial number of the customer's computer supports it.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • 2
    Both can be spoofed. You won't be able to get the MAC addressed used by the client if it goes through a router to reach the server (which is most likely to be the case). – Bruno Sep 03 '10 at 13:34
  • I think the software runs directly on the client machines, so it would be possible to get the MAC address. – msteiger Sep 03 '10 at 13:39
  • @Bruno - I'd say that any bit of information that is writable can be spoofed. As for getting the MAC address, a local program on the PC can extract it and then forward that on as data to the licensing system – Peter M Sep 03 '10 at 13:42
  • Sure, but that can be tweaked quite easily before the local program reads it. It's of course much easier to do on a virtual machine, but that can be done with actual hardware too. – Bruno Sep 03 '10 at 13:45
  • Don't care about spoofing. However we need to get this code when app starts, to validate the license file... not just when it goes online – Mr. Boy Sep 03 '10 at 14:06
  • Please, for any technique you mention like CPU id, give an example or a link. – Mr. Boy Sep 03 '10 at 14:10
  • @John: How could you validate the license file and verify that it is on that unique machine without a list of all machines? Anyway, you can get CPU serial number from WMI : http://msdn.microsoft.com/en-us/library/aa394373(VS.85).aspx IIRC. – Billy ONeal Sep 03 '10 at 14:32
  • 2
    @Billy: not sure I understand the question. Since we don't have the app web-enabled, the idea is on installation it will spit out a machine-specific code for them to email support. Support then generate a license file using this code which is sent back to user, who just drops it in the right folder. When the app starts, it checks the license is valid against the machine-specific key in some fashion – Mr. Boy Sep 03 '10 at 18:11
2

I think there no really easy and unique method so far discovered here.

  1. GetVolumeInformation retrieves not even close to unique ID.....
  2. To use any hardware serial is problematic because manufactures are not committed to supported it always and especially to keep it globally unique
  3. GetCurrentHwProfile retrieves GUID but it's value affected by minor! hardware changes...
  4. Using Product Key ... will bring U to deal with the stolen software - there lot of pirate installations over the globe.
  5. Creation of own GUID and preserving it under registry (in any place) will not prevent duplication by cloning of image ....
    etc... From my perspective of view the best way is combine: Volume ID + MAC's list + Machine SID + Machine Name. And obviously manage license policy on the server side ;0)

Regards Mickel.

Mickel
  • 21
  • 1
1

For a pretty brain dead test I am using the ProductID code of the OS and the computer name - both extracted from the registry. Not really secure, but its all pretend security anyway.

edit

To answer John's question about what keys I am reading:

SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID

SYSTEM\CurrentControlset\Control\ComputerName\ComputerName\ComputerName

Peter M
  • 7,309
  • 3
  • 50
  • 91
  • 2
    We tried this once but found that many corporate machines (cloned machines), or warezed machines, share the license code; it made this solution completely not viable. – tenfour Sep 03 '10 at 13:28
  • 1
    @tenfour - I agree totally that this is a stupid measure. But I am playing security theatre with my "product" so it doesn't deserve anything more than that. I remember when I looked into it last that even USB keys are being spoofed now. – Peter M Sep 03 '10 at 13:39
  • Wouldn't the Windows license mean it breaks if they upgrade the OS? But anyway, can you expand on your answer with the specific keys you access, or the code you use? – Mr. Boy Sep 03 '10 at 14:07
  • 1
    @John .. My "product" is an industry specific niche solution so I am always working 1 on 1 with the customers. So upgrades etc are not an issue - if they have a problem they'll come to me. As for the registry keys .. I'll have to kill you now :D – Peter M Sep 03 '10 at 14:58
  • 1
    thanks. Our situation is similar, it's a specialist product not one sold freely. So I guess we could provide new license keys if this happened. – Mr. Boy Sep 03 '10 at 18:13
1

If you want something a bit harder to spoof than whatever the machine itself can tell you, you'll probably need to provide a USB dongle dedicated for this purpose (not just a flash drive).

Bruno
  • 119,590
  • 31
  • 270
  • 376
  • 1
    when I looked a few years ago even USB keys were being hinted at as not being secure. But it all comes down to $$ - how much money you invest in security vs the cost to the people cracking it (plus how much it is worth to them). – Peter M Sep 03 '10 at 13:44
  • Yes, nothing is 100% secure, it's a matter of risk assessment indeed. – Bruno Sep 03 '10 at 13:49
  • I suggested this but client won't go for it. Info from the PC is fine, not worried about spoofing - but it needs to not change when they turn off WiFi or whatever. – Mr. Boy Sep 03 '10 at 14:04
  • I suspect most laptops have a wired network card. You could try read the MAC address from it, even if it's not used or the cable is not connected. – Bruno Sep 03 '10 at 14:18
1

How about using the serial number of the harddisk where windows is installed?

The function GetVolumeInformation() will give you such serial number. To access the ID assigned by the harddisk vendor instead of the ID assigned by Windows, you can use the Win32_PhysicalMedia Class.

To determine the drive where windows is installed, you could expand the variable %windir" by using the function ExpandEnvironmentStrings()

Another option, if your architecture allows, is to use UuidCreate() to generate a random GUID at installation time and save it permanently in the registry. This GUID can then be used as the ID as long as the registry remains. A new registry database is generally considered as a new installation.

A third option is to have a well-known server assigning the IDs. Upon starting up, the software could look up for the ID in the registry and if not found, would contact the server and supply it with its MAC address, hostname, harddisk serial number, Machine SID and any number of indentifyable information (keys).

The server then determines if the client is already registered or not based on the information given. The server could have a relaxed policy and for example only require most of the keys for a match, so that the mechanism would work even in the event of a complete wipe out of the registry and if part (but not all) of the hardware was replaced.

-1

How about using the serial number of a CPU. I remember Microsoft used to provide an api for this that would run the necessary assembler code and give you back all sorts of info about the CPU including serial number. Not sure if it'd work with AMD chips or not, I think it was intel specific.

Surely CPU Id is secure and static enough!!

display101
  • 2,035
  • 1
  • 14
  • 10
  • This would not work. The serial number of the CPU is not readable: https://stackoverflow.com/questions/21642347/cpu-id-using-c-windows – VLL Jul 26 '21 at 07:01