0

I'm writing a class that serializes a map of encrypted objects to a file, in order to maintain user login data etc.
The idea is to be able to always recover and decrypt the data using this class on the same machine, but not on other machines.
For this purpose (as suggested in this SO post and other articles) I am iterating over the Network Interfaces' hardware addresses, while using them to hash the default constant key:

byte[] key = getConstKey();
Enumeration<NetworkInterface> inters = networkInterface.getNetworkInterfaces();
while (inters.hasMoreElements()) {
    NetworkInterface inter = inters.nextElement();
    if (inter.getHardwareAddress() == null) {
      continue;
    }
    hashKeyAccordingToAddress(key, inter.getHardwareAddress());
}

This worked well and passed all my tests, until one day I took my laptop out the office...

Apparently, some network addresses have changed, or interfaces have been added / removed when I changed networks. My assumption was that only real hardware modifications will change the generated key. I guess I was wrong.

Is there a way to make this more robust, like, use only specific NetworkInterfaces that tends to be more stable? Or is there a better way to generate a machine unique-persistent key?

UPDATE: to be more specific, the issues begin when I connect to a VPN service from outside the office. Since some of the login details are used to connect to services over this VPN, my solution becomes useless..

Community
  • 1
  • 1
Elist
  • 5,313
  • 3
  • 35
  • 73
  • You could use information from hardware that hardly changes like HD serial number, motherboard serial number... – Jorge Campos Dec 10 '15 at 13:08
  • Does java utilizes getting such information? The only hardware info I could get was the inet addresses. – Elist Dec 10 '15 at 13:12
  • AFAIK there is no API to do this directly from java, you have to call OS commands to do so. For instance in Windows, you can use a WMI call like: `wmic diskdrive get serialnumber` – Jorge Campos Dec 10 '15 at 13:26
  • wmic only works if WMI is activated, running and has the according information - its generally the worst possible approach to use wmic, also : its a very bad idea to gather information from network cards as these can be fully configured and/or even configure themselves, which basically means that your hardware data may change at any time. The only somewhat stable information may be CPU model, mainboard model and possibly even GPU -- but i'd be careful with that since the GPU can be exchanged pretty easily. – specializt Dec 10 '15 at 13:32
  • 2
    You could try checking whether `isVirtual` is false for an interface before adding it's hash. That way you should confine yourself to the machine's physical interfaces. – Will Dec 10 '15 at 14:12
  • Thanks, looks like the solution I'm looking for! – Elist Dec 10 '15 at 21:41
  • @Will, I've tried to filter out `isVirtual()` interfaces, but it didn't help. The interface that is added when I connect to the VPN is `Microsoft ISATAP adapter` which is not virtual. I have noticed that it has an address value that looks like a default one ({0, 0, 0, 0, 0, 0, 0, -32}) so I filtered such addresses out. Now it works fine. – Elist Dec 11 '15 at 10:43
  • windows networking is very complex - and sometimes the third-party driver implementations are extremely buggy ... even major NIC manufacturers like Intel have bugs _(even worse : missing or faulty NIC properties)_ in their drivers ... all of these problems need to be considered once you start filtering network adapters and the sad truth is : you will never find a complete, absolutely reliable solution. Dont read network adapter info if you want to create encryption/decryption keys or machine IDs, even. Thats a design flaw. With wmic and the likes you will only make it even worse. – specializt Dec 11 '15 at 11:38

1 Answers1

2

You may use the Trusted Platform Module (TPM), most newer Systems come with one already available. See This Library for a possibly easy way to access the TPM. Store your unique key on the TPM.

Jonas Köritz
  • 2,606
  • 21
  • 33
  • Looks interesting and useful. Yet I am not sure it solves all my use cases, since I need to often serialize encrypted complex objects. Also `most newer systems` is not enough for me. I have no guarantee for my users systems.. – Elist Dec 10 '15 at 13:28