It is sometimes beneficial to have a unique identifier for the system on which we are currently running. For example, if you sell software, you may wish to verify that the computer is licensed or activated. A question on CSSM today reminded me of this issue.
A trivial solution to this question is to use the built-in license function. Unfortunately, this does not work with a multi-system network/floating Matlab license, nor on deployed (compiled) systems.
While Matlab doesn’t have a built-in solution, we can use simple Java to access system information. There are several possible approaches. Here are several alternatives:
Windows SID
A Windows-specific approach is to return the Window Domain Controller’s SID (Security ID). This is a unique identifier that changes with each computer/user. Java enables direct access to this identifier, and we can run this directly in Matlab:
>> sid = get(com.sun.security.auth.module.NTSystem,'DomainSID') sid = S-1-5-21-292311649-1610625687-3346456317 |
The exact same value can also be gotten directly from the Windows Registry:
% Note: scanning HKEY_-- USERS node names is better, but Matlab's winqueryreg() can't do that... rootkey = 'HKEY_CURRENT_-- USER'; subkey = 'Software\Microsoft\Windows\CurrentVersion\Group Policy\GroupMembership'; count = winqueryreg(rootkey,subkey,'Count'); for idx = 0 : double(count)-1 % Note: double() is needed for Matlab 6 compatibility val = winqueryreg(rootkey,subkey,['Group' char('0'+idx)]); dashes = find(val=='-'); if length(dashes) > 4, sid = val(1:dashes(end)-1); break; end % short ids are phoney end |
This later version, although less simple than the first alternative (Java-based approach) above, has the benefit of working on old Matlab releases such as R12 (6.0) where the Java approach fails. For this reason, my getsid utility on the File Exchange uses the registry approach.
Other platforms
For non-Windows systems, both of the above approaches fail. For such platforms, we can use the Ethernet addresses of the computer’s network cards. This should be pretty unique for any practical effect:
sid = ''; ni = java.net.NetworkInterface.getNetworkInterfaces; while ni.hasMoreElements addr = ni.nextElement.getHardwareAddress; if ~isempty(addr) addrStr = dec2hex(int16(addr)+128); sid = [sid, '.', reshape(addrStr,1,2*length(addr))]; end end >> sid sid = .89ECC872C85C.8AFE928FEDB4.8262278A1CCA.899919B50FC9 |
This again uses Java (which unfortunately fails on R12 aka 6.0). The benefit is that it is entirely cross-platform, working wherever Matlab runs (including Windows), on any Matlab release that supports Java (I think R13 aka 6.5 should be the earliest).
Do you have another way to generate unique identifiers? If so, please share your experience in a comment.
To limit the use of my softwares , I ask end-users the hostname of their machines or their login
For the login for example I use the following piece of code which is cross-platform
Then I compare the username string with what I expect to get.
Aurélien
You can use flexlm which always ships with MATLAB. Look for
or:
Keep in mind Yair’s note that using the license manager does not work in deployed applications and may not give reliable results in MATLAB network served instances.
The form that you can use in a function is:
The harddisk ID and the creation date of the drive containing the OS are most likely unique.
Under Windows (XP, and newer?) POWERCFG replies a list, which contains the hardware IDs of all devices, which have been connected in the past:
It is hard to parse the replied list, e.g. to find a specific ID of the harddisk. But if you know a ID, e.g. the vendor ID of an USB-stick, it is easy to check if this string appears anywhere in the list.
Kind regards, Jan
I don’t know how portable it is, but on Windows I use
BTW, great site!
Nathan
@Nathan – thanks for the compliment.
Your method is actually portable (cross-platform), since it is based on generic plain-vanilla Java. Unfortunately, I’m afraid it is not very unique since it just returns the computer name, which is non-unique by definition. By the way, on Windows you can use the following much simpler method to get this computer name:
A small change for your Java approach:
Instead of
this might be nicer:
@Jan – I humbly stand corrected 🙂
Hi,
for licensing I always use the MAC address of (one of) the network controllers. This address is absolutley unique for each network device worldwide.
The only way to access this I know of is using C/C++ compiled to a *.dll which can then be called from MATLAB using calllib
If interested I can post the code from the function to access the device.
And yes, this is a great site, learned a lot about Java in MATLAB and using lots of it.
Keep up Yair!
Matthias
@Matthias – thanks 🙂 The code I posted above does exactly what you say, specifying the MAC addresses of all the computer’s network controllers. Please take a look – it’s actually quite simple and does not require any DLL, so it works on both Windows and non-Windows platforms.
Thanks for the code, it’s very helpful, however in the {‘win32′,’win64’} i had to add “+1” to get the right MAC address. without the preceding “=” :
Here is my practice for regexp. For all OS, always take the first mac_add pattern in the string output.
This is a really good guide, especially for those developing software (like you say) who are fearful that it will get copied.
SID is not an absolutely secure way to protect your license.
There are many software tool which can modify computer sid, such as NewSid software.
really helpful
How unique is SID? Can be there 2 identical SIDs in the world?
Thomas – of course: any computer-generated id can be spoofed and hacked. You can never fully protect yourself from this. But if you’re looking at normal legal behavior, then it should be unique for any practical purposes.
@Yair – sorry, I meant not SID but that second method, where sid = .89ECC872C85C.8AFE928FEDB4.8262278A1CCA.899919B50FC9
Is it the MAC address? Because MAC address has 12 digits. My SID (this 48 digits long) is different from my MAC. Thanks.
@Thomas – in this case you have 4 separate MAC addresses, from 4 separate network devices. Run the following in your Matlab command prompt to see the list (look at the “Physical Address” rows):
This again is only unique if the user does not fool around with the MACs…
Yes, they are different, this is why i am confused a bit. The SID method gives .D6CDDF05903C.8888888600000000.8888888600000000.8888888600000000
IPconfig says:
50-E5-49-50-53-7A (this is the ethernet adapter)
00-00-00-00-00-00-00-E0
00-00-00-00-00-00-00-E0
00-00-00-00-00-00-00-E0
@Thomas – it’s simply a different representation of the data. Here’s an implementation that should return more legible results:
oh, i see.. the new method indeed gives .00000000000000E0.50E54950537A 🙂
thank you for your clarification. could you please delete my mac addresses, they were not intended to go public 🙂
Next time don’t post on a public blog something that you don’t want to appear publicly!
Newer Macs have a hardware UUID. Note that Apple won’t allow a program that uses this in the App Store, but this probably won’t affect too many people writing deployed applications. Here is a little routine that accesses the system profile using the system_profiler command.
The UDID (unique device ID) is returned in profile.Hardware_UUID. This is probably more reliable than the MAC address of EN0.
Great post! I’m not very familiar with the network interfaces being referenced here, but it seems like the java-based cross-platform method concatenates all network interfaces. Does that mean that the SID returned by this method will change if a network interface is added or removed? Is it even possible to add or remove this type of network interface? Thanks!
@Mitchell – in most cases the user wants a single string identifier for the computer, that uniquely identifies it with a distinct fingerprint that is different from any other computer. The network interface (MAC) addresses are reported by the operating system, and naturally change when you add or remove a network card or adapter. It is up to you to decide which of the MAC addresses should be included in the fingerprint: if you include all of them, it certainly makes your fingerprint unique, but might include addresses that change frequently (e.g. VPN, WiFi, or virtual interfaces). On the other hand, if you ignore too many interfaces, your SID might be easier to spoof. Different operating systems have different ways of handling network interface MAC addresses, and you should consider this as well. For example, Windows and Linux addresses are pretty stable, but MacOS constantly changes the addresses when you connect/disconnect a network interface. MacOS also changes the computer’s hostname automatically, without any user approval, which is a PITA. In short, having a stable, unique SID that is less prone to spoofing requires some thought. If you need my assistance with this, please contact me privately (altmany at gmail).