views:

852

answers:

3

Question: I have to come up with unique ID for each networked client, such that:

  • it (ID) should persist once client software is installed on target computer, and should continue to persist if software is re-installed on same computer and same OS installment,
  • it should not change if hardware configuration is modified in most ways (except changing the motherboard)
  • When hard drive with client software installed is cloned to another computer with identical hardware configuration (or, as similar as possible), client software should be aware of that change.

A little bit of explanation and some back-story:

This question is basically age old question that also touches topic of software copy-protection, as some of mechanisms used in that area are mentioned here. I should be clear at this point that I'm not looking for a copy-protection scheme. Please, read on. :)

I'm working on a client-server software that is supposed to work in local network. One of problems I have to solve is to identify each unique client in network (not so much of a problem), so that I can apply certain attributes to every specific client, retain and enforce those attributes during deployment lifetime of a specific client.

While I was looking for a solution, I was aware of following:

  • Windows activation system uses some kind of heavy fingerprinting mechanism, that is extremely sensitive to hardware modifications,
  • Disk imaging software copies along all Volume IDs (tied to each partition when formatted), and custom, uniquely generated IDs during installation process, during first run, or in any other way, that is strictly software in its nature, and stored in registry or on hard drive, so it's very easy to confuse two

Obvious choice for this kind of problem would be to find out BIOS identifiers (not 100% sure if this is unique through identical motherboard models, though), as that's the only thing I can rely on, that isn't duplicated, transferred by cloning, and that can't be changed (at least not by using some user-space program). Everything else fails as either being not reliable (MAC cloning, anyone?), or too demanding (in terms that it's too sensitive to configuration changes).

Sub-question that I'd like to ask is, am I doing it correctly, architecture-wise? Perhaps there is a better tool for task that I have to accomplish...

Another approach I had in mind is something similar to handshake mechanism, where server maintains internal lookup table of connected client IDs (which can be even completely software-based and non-unique at any given moment), and tells client to come up with different ID during handshake, if duplicate ID is provided upon connection. That approach, unfortunately, doesn't play nicely with one of requirements to tie attributes to specific client during lifetime.

+1  A: 

It seems to me that you should construct the unique ID corresponds your requirements yourself. This ID can be constructed as a hash (like MD5, SHA1 or SHA512) from the information which are important for you (some information about software and hardware component).

You can makes your solution more secure if you sign such hash with your own private key and your software verify during the starting, that the key (signed hash value) is signed (only public key must be installed together with your software). One can expand such kind of solution with different online services, but corporate clients could find online services not so nice.

Oleg
Software component is not reliable, as it can easily be cloned, right? Combination of two could be a better solution, as you proposed, since that could enable remote server to identify cloned clients, so to call them. Good idea. Thanks.
mr.b
I mean, that you can produce a string or byte array with all information (concatenation of this information) which are important and are **invariant during the cloning of computer**. Then you calculate a hash from this array of bytes. This hash value will be your unique ID. You save such hash value during software installation. Every time as your software will be started you calculate the ID (hash) one more time and compare with the saved during installation value. Is that not what you want? How to read hardware information is not a problem. There are a lot of ways inclusive WMI.
Oleg
Although this is very close to what I'm looking for, another poster has provided more to-the-point answer. However, I must emphasize that I like your suggestion to build hash based on "information about software and hardware component". This led me to think of additional feature that I might incorporate, which is ability to detect cloned clients, by having separate hw and sw IDs - say that hw ID is truly unique, and sw ID might not be unique, in which case, it's clearly cloned instance.
mr.b
If you don't know how to read BIOS or MAC information, you should asked this in your question. Moreover, you don't wrote whether you use .NET or unmanaged code, C/C++ or VB and so on. For C/C++ developer usage of WMI is not the easiest and not the best way, there are a lot of easy C-like Windows API which can give you information what you look for. Your question sound much more as you are looking for an idea for constructing of IDs like Microsoft and other this do. I just shortly explain the main idea of such implementations. Good luck.
Oleg
Thanks, I was probably too descriptive, from best intent to explain what I want to accomplish. I didn't mean to say that I was looking for exact code solution, but I was looking for a piece of uniquely-identifiable information, such as BIOS and/or Motherboard ID string. How would I read it is another story (despite having gotten precise location where I can read it from). True, WMI might not be the way to go, as you have suggested. Sorry for confusion. To be perfectly honest, I was looking for a second opinion on the subject, which is exactly what I got from both of you. Thank you very much!
mr.b
To be even more honest, both of you gave perfectly acceptable answers, but instead of not marking any answer as "the answer", I have figured it would be better to mark one that is IMO closer to what I was expecting, sort of.
mr.b
It's not a problem. I have enough reputation points. You welcome. It is just funny if I find a question which I stay me some year ago. I know too exactly how to implement what you are searching for because of my previous experience. So you welcome and good luck!
Oleg
+2  A: 

What you're looking for is the Windows WMI. You can get the motherboard ID (which is unique across the same type of motherboard) or many many other types of unique identifiers and come up with some clever seeded function to generate a UHID. Whoa did I just make up an acronym?

And if you're looking specifically for getting the Motherboard (BIOS) ID:

WMI class: Win32_BIOS
Namespace: \Root\Cimv2

Documentation: http://msdn.microsoft.com/en-us/library/aa394077(VS.85).aspx
Sample code: http://msdn.microsoft.com/en-us/library/aa390423%28VS.85%29.aspx

Edit: You didn't specify a language (and I assumed C++), but this can be done in Java (with a COM driver), and any .NET language, as well.

David Titarenco
Correct, I didn't specify a language, because I find that specific language is irrelevant to the question at hand. I'm interested in a higher level way to accomplish this. I find your answer very precise. The only thing I have to find out is how backwards-compatible this interface is, ie. how old motherboard are supported using this method?
mr.b
I'm pretty sure all BIOSs have been standardized since the early to mid 90s. The WMI has been around since Windows 2000 (and is available as a patch to Windows 95 and Windows NT). In short, you have nothing to worry about :) It's fully backwards-compatible unless you're installing your software on Windows 3.1 or computers that were built 30 years ago.
David Titarenco
Damn, early-to-mid 90s were 15-20 years ago... Talk about time flying! I was aware that in recent past (say, 10 years ago and onwards) most manufacturers had these standardized, and was interested in hearing how much in time it goes back. Now I have my answer. Thanks.
mr.b
I have returned with my findings, regarding support for unique, BIOS-related identifier. Unfortunately, none of 4-5 mainboards (all 1-2 years old) had BIOS SerialNumber. Am I doing something wrong? I was using mentioned property to generate unique IDs, but to no avail... Any ideas?
mr.b
Anyhow, turns out that this is not a solution to my problem. I'll go with a generic answer.
mr.b
A: 

Many programs use the hostId in order to build a license code (like those based on FlexLM). Have a look at what Matlab does depending on the operative system:

http://www.mathworks.com/support/solutions/en/data/1-171PI/index.html

Also have a look at this question:

http://stackoverflow.com/questions/328936/getting-a-unique-id-from-a-unix-like-system

Once I also saw some programs basing their licenses on the serial number of the hard drive, an maybe that is the less likely think to change. Some would suggest to use the MAC of your ethernet card, but that can be reprogrammed.

Francisco Garcia
Good thing about this project is that users don't have to go through an effort to change MAC, since they would gain absolutely nothing by doing it (as it's not form of software protection). But, due to nature of program, hard disk serial number is not an option, unfortunately :( MAC is troublesome, since even networked computers don't expose their MAC address when NIC is disabled... :( That leaves me with probability that majority of users won't mess with their NIC (as they shouldn't, since this program is closely tied with network).
mr.b