Is there a unique computer identifier that can be used reliably even in a virtual machine?
I'm writing a small client program to 开发者_StackOverflow社区be run on a terminal server. I'm looking for a way to make sure that it will only run on specified server and in case it is removed from the server it will stop functioning.
I understand that there are no methods to make it 100% secure, none the less I want to make it difficult for most power users to be able to do it.
I was looking at different Unique Identifiers like Processor ID, Windows Product ID, Computer GUID and other UIs. Because the terminal server is a virtual machine, I cannot locate anything that is completely unique to this machine.
Any ideas on what I should look into to make this mostly secure. I do not have time or the need to make it as secure as possible, because it will defeat the purpose of the application itself.
I do not want to user MAC address. Even though it is unique to each machine it can be spoofed by following instructions found on internet.
As far as Microsoft Product ID, because our system team clones VM servers and we use corporate volume key, I found already two servers that I have access to that have same Product ID Number. I have no Idea how many others out there that have same Product ID
Alternatively instead of trying to identify the machine, I might be better off by identifying the user and create group based permission handled through AD for access to this software.
By design, uniquely identifying a virtual machine is difficult; anything that allowed you to uniquely identify it would imply that it was not fully virtual (because cloning a virtual machine should produce an identical machine).
- Create a heartbeat application on the host machine that communicates with the VM via a loopback network adapter.
- Have the heartbeat application refuse to run if it is not able to uniquely identify the host machine.
- Have the main application refuse to run if the heartbeat application is not running.
You will need to find a way to ensure that the heartbeat application cannot be spoofed too easily.
It is not possible to protect the terminal program 100%. This question is equivalent to trying to prevent software piracy.
The best thing I've found is the BIOS UUID - but it's far from perfect for your use case.
The SMBIOS UUID available inside the VM is also used by the VMware hypervisor and management tools as VirtualMachine.config.uuid (See: the uuid property on this page). This means it is guaranteed to be unique on a particular host, or in a particular vCenter. However, it can be duplicated on separate hosts or separate vCenter installations.
Also, the BIOS UUID on a virtual machine is mutable. It can be changed through the API (though not easily through the client).
This probably approaches your 95% mark, as it would take some special effort and setup to duplicate the VM exactly.
However, from a virtualization-enablement perspective (including things like VM disaster recovery, and future upgrades of virtualization software): using a hardware ID like the UUID or MAC address causes all sorts of problems. When they want to rev the OS version underneath your software, usually by creating a new virtual machine, they would need to manually edit the VM config for both servers to change the UUID to match. Using the MAC, if they change the network architecture, your software requires that VM to be a special case. These things just cause headaches for a virtual admin (but they might be the exact headaches you're trying to cause - only you know for sure).
I'd recommend using the permissions-based approach you mention, or even a concurrent-licensing server if necessary. But I'm coming from a heavily-virtual background where hardware-tied licenses are a headache already.
Simplest solution is to use the mac address, but note that it is easily changed on Windows by editing the registry. I'd say less than 5% of people know how to do that though.
Here's how to get the mac address in C#:
System.Net.NetworkInformation.NetworkInterface.GetPhysicalAddress();
You can tie the license to the MAC address of the network card (or cards, if there are several).
Of course, changing the network card would then stop your software from working.
If/When TPM becomes standard on servers, you should be able to use it to authenticate the server.
You can get the PC's MAC Address as shown here: http://www.java2s.com/Code/CSharp/Network/GetMacAddress.htm
Of course, this approach is not without flaws. There are other approaches listed in this post, which is similar, but not an exact duplicate: What's a good way to uniquely identify a computer?
expanding on the macaddress approach. you could use the macaddress with an md5 function around it with a SALT that was only known to the system owners. this way, the macaddress is useless without knowing the SALT.
just my tuppence worth.. :)
[edit] - see also here for c# example on hashing/salting etc:
MD5 hash with salt for keeping password in DB in C#
http://www.obviex.com/samples/hash.aspx
If you want 95% I'd go with the Mac ID - it can be spoofed, but by default is unique for the machine.
精彩评论