Подтвердить что ты не робот

Как получить уникальный идентификатор компьютера в Java (например, идентификатор диска или идентификатор материнской платы)

Я хотел бы получить уникальный идентификатор компьютера с Java, Windows, MacOS и, если возможно, Linux. Это может быть диск UUID, системная плата s/n...

Runtime.getRuntime().exec может использоваться (это не апплет).

Идеи?

4b9b3361

Ответ 1

Обычно используется MAC-адрес, связанный с сетевой картой.

Адрес доступен на Java 6 через следующий API:

Java 6 Документы для аппаратного адреса

Я не использовал его в Java, но для других приложений идентификации сети это было полезно.

Ответ 2

Проблема с MAC-адресом заключается в том, что к компьютеру подключено много сетевых адаптеров. Большинство из новейших имеют по умолчанию два (wi-fi + кабель). В такой ситуации нужно было бы знать, какой MAC-адрес адаптера следует использовать. Я протестировал решение MAC в своей системе, но у меня есть 4 адаптера (кабель, WiFi, адаптер TAP для Virtual Box и один для Bluetooth), и я не смог решить, какой MAC я должен принять... Если кто-то решит использовать адаптер который в настоящее время используется (имеет назначенные адреса), появляется новая проблема, поскольку кто-то может взять его/ее ноутбук и переключиться с кабельного адаптера на wi-fi. При таком условии MAC, сохраненный при подключении ноутбука через кабель, теперь будет недействительным.

Например, это адаптеры, которые я нашел в моей системе:

lo MS TCP Loopback interface
eth0 Intel(R) Centrino(R) Advanced-N 6205
eth1 Intel(R) 82579LM Gigabit Network Connection
eth2 VirtualBox Host-Only Ethernet Adapter
eth3 Sterownik serwera dostepu do sieci LAN Bluetooth

Код, который я использовал для их перечисления:

Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
while (nis.hasMoreElements()) {
    NetworkInterface ni = nis.nextElement();
    System.out.println(ni.getName() + " " + ni.getDisplayName());
}

Из вариантов, которые прослушиваются на этой странице, наиболее приемлемым для меня, и тем, который я использовал в своем решении, является тот, который @Ozhan Duz, другой, похожий на @finnw ответ, где он использовал JACOB, и стоит упомянуть com4j - образец, который использует WMI, доступен здесь:

ISWbemLocator wbemLocator = ClassFactory.createSWbemLocator();
ISWbemServices wbemServices = wbemLocator.connectServer("localhost","Root\\CIMv2","","","","",0,null);
ISWbemObjectSet result = wbemServices.execQuery("Select * from Win32_SystemEnclosure","WQL",16,null);
for(Com4jObject obj : result) {
    ISWbemObject wo = obj.queryInterface(ISWbemObject.class);
    System.out.println(wo.getObjectText_(0));
}

Это приведет к печати информации о компьютере вместе с серийным номером компьютера. Обратите внимание, что все классы, требуемые в этом примере, должны быть сгенерированы maven-com4j-plugin. Пример конфигурации для maven-com4j-plugin:

<plugin>
    <groupId>org.jvnet.com4j</groupId>
    <artifactId>maven-com4j-plugin</artifactId>
    <version>1.0</version>
    <configuration>
        <libId>565783C6-CB41-11D1-8B02-00600806D9B6</libId>
        <package>win.wmi</package>
        <outputDirectory>${project.build.directory}/generated-sources/com4j</outputDirectory>
    </configuration>
    <executions>
        <execution>
            <id>generate-wmi-bridge</id>
            <goals>
                <goal>gen</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Над конфигурацией скажет плагин генерировать классы в каталоге target/generated-sources/com4j в папке проекта.

Для тех, кто хотел бы видеть готовое к использованию решение, я включаю ссылки на три класса, которые я написал, чтобы получить SN для Windows, Linux и Mac OS:

Ответ 3

В качестве альтернативного способа решения finnw wmic утилита командной строки может использоваться для запроса серийных номеров устройств. Без внешней зависимости большую часть WMI можно установить с помощью wmic.

import java.util.Scanner;

public class GetBiosSerialNumber {

    public static void main(String[] args) throws Throwable {
        // wmic command for diskdrive id: wmic DISKDRIVE GET SerialNumber
        // wmic command for cpu id : wmic cpu get ProcessorId
        Process process = Runtime.getRuntime().exec(new String[] { "wmic", "bios", "get", "serialnumber" });
        process.getOutputStream().close();
        Scanner sc = new Scanner(process.getInputStream());
        String property = sc.next();
        String serial = sc.next();
        System.out.println(property + ": " + serial);
    }
}

Ответ 4

Проект OSHI предоставляет независимые от платформы аппаратные утилиты.

Зависимость от Maven:

<dependency>
    <groupId>com.github.dblock</groupId>
    <artifactId>oshi-core</artifactId>
    <version>LATEST</version>
</dependency>

Например, вы можете использовать что-то вроде следующего кода, чтобы однозначно идентифицировать машину:

import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.OperatingSystem;

public class ComputerIdentifier
{
    public static String generateLicenseKey() throws Exception
    {
        SystemInfo systemInfo = new SystemInfo();
        OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
        HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
        CentralProcessor centralProcessor = hardwareAbstractionLayer.getProcessor();

        String vendor = operatingSystem.getManufacturer();
        String processorSerialNumber = centralProcessor.getSystemSerialNumber();
        String processorIdentifier = centralProcessor.getIdentifier();
        int processors = centralProcessor.getLogicalProcessorCount();

        String delimiter = "#";

        return vendor +
                delimiter +
                processorSerialNumber +
                delimiter +
                processorIdentifier +
                delimiter +
                processors;
    }

    public static void main(String[] arguments) throws Exception
    {
        String identifier = generateLicenseKey();
        System.out.println(identifier);
    }
}

Выход для моей машины:

Microsoft#57YRD12#Intel64 Family 6 Model 60 Stepping 3#8

Ваш выход будет отличаться, поскольку по крайней мере серийный номер процессора будет отличаться.

Ответ 5

Что вы хотите сделать с этим уникальным идентификатором? Возможно, вы можете делать то, что хотите, без этого идентификатора.

Возможно, MAC-адрес является одним из вариантов, но это не надежный уникальный идентификатор, так как пользователь может изменить MAC-адрес компьютера.

Чтобы получить идентификатор материнской платы или процессора, нажмите ссылку .

Ответ 6

Только в Windows вы можете получить идентификатор материнской платы с помощью WMI через COM-мост, например JACOB.

Пример:

import java.util.Enumeration;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.EnumVariant;
import com.jacob.com.Variant;

public class Test {
    public static void main(String[] args) {
        ComThread.InitMTA();
        try {
            ActiveXComponent wmi = new ActiveXComponent("winmgmts:\\\\.");
            Variant instances = wmi.invoke("InstancesOf", "Win32_BaseBoard");
            Enumeration<Variant> en = new EnumVariant(instances.getDispatch());
            while (en.hasMoreElements())
            {
                ActiveXComponent bb = new ActiveXComponent(en.nextElement().getDispatch());
                System.out.println(bb.getPropertyAsString("SerialNumber"));
                break;
            }
        } finally {
            ComThread.Release();
        }
    }
}

И если вы решите использовать MAC-адрес для идентификации машины, вы можете использовать WMI, чтобы определить, подключен ли интерфейс через USB (если вы хотите исключить USB-адаптеры.)

Также возможно получить идентификатор жесткого диска через WMI, но это ненадежно.

Ответ 7

Будьте осторожны при использовании MAC-адреса в качестве идентификатора. Я испытал несколько ошибок:

  • В OS X порты Ethernet, которые не активны/не отображаются, не отображаются в NetworkInterface.getNetworkInterfaces() Enumeration.
  • Безумно легко изменить MAC-адрес на карточках, если у вас есть соответствующие привилегии ОС.
  • Java имеет привычку неправильно идентифицировать "виртуальные" интерфейсы. Даже с помощью NetworkInterface.isVirtual() не всегда будет говорить вам правду.

Даже с вышеупомянутыми проблемами я все еще считаю это лучшим чистым Java-подходом к аппаратной блокировке лицензии.

Ответ 8

Не знаю всех ваших требований. Например, вы пытаетесь однозначно идентифицировать компьютер со всех компьютеров в мире или просто пытаетесь однозначно идентифицировать компьютер у множества пользователей вашего приложения. Кроме того, можете ли вы создавать файлы в системе?

Если вы можете создать файл. Вы можете создать файл и использовать время создания файла как свой уникальный идентификатор. Если вы создадите его в пространстве пользователя, он однозначно определит пользователя вашего приложения на конкретной машине. Если вы создали его где-то глобальным, то он мог бы однозначно идентифицировать машину.

Опять же, как и большинство вещей, как быстро это достаточно быстро.. или в этом случае, насколько уникальным является достаточно уникальный.

Ответ 10

Использование MAC идентификатора является наиболее простым способом, если задача заключается в регистрации уникального идентификатора системы.

изменение идентификатора mac возможно, даже изменение других идентификаторов системы также возможно, что соответствующее устройство заменено.

поэтому, если не требуется идентификация уникального идентификатора, мы не сможем найти подходящее решение.

Однако приведенная ниже ссылка помогает извлечь MAC-адреса. http://www.stratos.me/2008/07/find-mac-address-using-java/

Ответ 11

В java-программах, которые я написал для выпуска, я использовал серийный номер материнской платы (это то, что я использую для использования Windows); однако это работает только с окнами, так как моя функция создает временный VB script, который использует WMI для извлечения значения.

public static String getMotherboardSerial() {
      String result = "";
        try {
          File file = File.createTempFile("GetMBSerial",".vbs");
          file.deleteOnExit();
          FileWriter fw = new FileWriter(file);

          String vbs =
             "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
            + "Set colItems = objWMIService.ExecQuery _ \n"
            + "   (\"Select * from Win32_ComputerSystemProduct\") \n"
            + "For Each objItem in colItems \n"
            + "    Wscript.Echo objItem.IdentifyingNumber \n"
            + "Next \n";

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

Ответ 12

Для однозначной идентификации машины Windows. Убедитесь, что вы используете wmic для стратегии альтернативных методов. Поскольку "wmic bios get serialnumber" может не работать на всех машинах, вам могут потребоваться дополнительные методы:

# Get serial number from bios
wmic bios get serialnumber
# If previous fails, get UUID
wmic csproduct get UUID
# If previous fails, get diskdrive serialnumber
wmic DISKDRIVE get SerialNumber

Ресурсы: Лучший способ уникальной идентификации машины Windows http://www.nextofwindows.com/the-best-way-to-uniquely-identify-a-windows-machine/