Nathan F.
Nathan F.

Reputation: 3469

Computer specific ID?

I'm trying to generate a specific computer id using Java. I've thought about things like Hard Drive Serials, or Windows Serial Keys, CPU ID's, or MAC Addresses, but other computers could have the same ones.. For instance, If someone pirates a copy of Windows 7 they could have the same serial as someone.. I was wondering if someone could give me a way to generate a computer specific ID that is never changed and is retrievable using Java?

I did some research and found some useful functions. And, I was thinking something like this. But if they change their hardware, It will change the computer ID. Anyone know of something I can use?

public String getComputerID(){
    InetAddress ip = InetAddress.getLocalHost();
    NetworkInterface network = NetworkInterface.getByInetAddress(ip);
    byte[] mac = network.getHardwareAddress();
    String sn = getSerialNumber("C");
    String cpuId = getMotherboardSN();
    return MD5(mac + sn + cpuId);
}


public String MD5(String md5) {
try {
        java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
        byte[] array = md.digest(md5.getBytes());
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < array.length; ++i) {
        sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
    }
        return sb.toString();
    } catch (java.security.NoSuchAlgorithmException e) {
    }
    return null;
}

public String getSerialNumber(String drive) {
String result = "";
    try {
    File file = File.createTempFile("realhowto",".vbs");
    file.deleteOnExit();
    FileWriter fw = new java.io.FileWriter(file);

  StringBufferring vbs = "Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n"
                +"Set colDrives = objFSO.Drives\n"
                +"Set objDrive = colDrives.item(\"" + drive + "\")\n"
                +"Wscript.Echo objDrive.SerialNumber";  // see note
    fw.write(vbs);
    FileWriter.close();
      Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
      BufferedReader input =
        new BufferedReader
        (new InputStreamReader(p.getInputStream()));
    String line;
    while ((line = input.readLine()) != null) {
        result += line;
    }
    input.close();
    }
    catch(Exception e){
        e.printStackTrace();
    }
    return result.trim();
}

public String getMotherboardSN() {
String result = "";
try {
File file = File.createTempFile("realhowto",".vbs");
file.deleteOnExit();
FileWriter fw = new java.io.FileWriter(file);

String vbs =
"Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
+ "Set colItems = objWMIService.ExecQuery _ \n"
+ " (\"Select * from Win32_BaseBoard\") \n"
+ "For Each objItem in colItems \n"
+ " Wscript.Echo objItem.SerialNumber \n"
+ " exit for ' do the first cpu only! \n"
+ "Next \n";

fw.write(vbs);
fw.close();
Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
result += line;
}
input.close();
}
catch(Exception e){
e.printStackTrace();
}
return result.trim();
}

Upvotes: 6

Views: 8874

Answers (3)

Nathan F.
Nathan F.

Reputation: 3469

After looking over everyone's input, and quite a few google searches I've come to this conclusion

In technicality, Seeing as if you removed a component and replaced it, it would be an entirely new computer, to generate a true computer specific ID you would have to get a specific variable from each component in the system, (i.e. the serial number), combine them all, and that would be a "Computer Specific ID". However, Since a computer is so susceptible to change, the closest one would get is to take the LEAST LIKELY TO CHANGE component, and us a specific variable from it for the computer ID. This will generally be the motherboard or another component that is not likely to change. So, The closest one might get would be the serial number (or some other child component) of the motherboard.. In my personal opinion.

Why is the motherboard the least likely to change?

It seems that the motherboard is the last part people consider changing, especially on newer computers. They won't normally change it unless it is absolutely required. Another viable option would be the NIC. It's honestly up to you what piece of hardware you use, But the best one to use would be the one that you think would be the least likely to change.

Upvotes: 1

user3158918
user3158918

Reputation: 131

For Disk/Volumes it could be:

    /**
     * Execute system console command 'vol' and retrieve volume serial number
     *
     * @param driveLetter - drive letter in convetion 'X:'
     * @return - Volume Serial Number, typically: 'XXXX-XXXX'
     * @throws IOException
     * @throws InterruptedException
     */
    static final String getVolumeSerial(String driveLetter) throws IOException, InterruptedException {
        Process process = Runtime.getRuntime().exec("cmd /C vol " + driveLetter);
        InputStream inputStream = process.getInputStream();
        InputStream errorStream = process.getErrorStream();
        if (process.waitFor() != 0) {
            Scanner sce = new Scanner(errorStream);
            throw new RuntimeException(sce.findWithinHorizon(".*", 0));
        }
        Scanner scn = new Scanner(inputStream);
        // looking for: ': XXXX-XXXX' using regex
        String res = scn.findWithinHorizon(": \\w+-\\w+", 0);
        return res.substring(2).toUpperCase().trim();
    }

Upvotes: 1

Yair Zaslavsky
Yair Zaslavsky

Reputation: 4137

I actually do believe you should use something from hardware profile.
A computer can be considered as a set of pieces of hardware, including the network interface. A typical pattern can be to have combination of a MAC address and a generated ID by a management system that manages computers over the network.
The MAC address to identify uniquely the machine during a registration process to the management system.
As a result of the registration, the management system can return a generated UniqueId,
to be stored on the computer that registered to it, and will later on be used.
After a successful registration, you can replace the network interface card, as the computer does not depend on the MAC address to be identified.
You can also consider using the linux dmidecode utility
(for linux machines,
as you provided a win-based solution,
so for our linux readers,
I would like to suggest a linux alternaties) (if the machine you want to uniquely identify has linux and dmidecoe installed).
Using dmidecoe you can get more hardware profile, and perform some hash function on it, and generate a unique ID that will identify uniquely (with high probability, to be precise) your machine.
Read more about dmidecode here.
Of course, in case you go to "get information on hardware from the operating system" approach (which is dmidecode or what you suggested at the part after getting the MAC address,
You need for a cross platform code to check what is the OS the java program runs on, you do that using this:

System.getProperty("os.name");

Upvotes: 4

Related Questions