2009-12-31 7 views
51

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

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

Идеи?

+1

Это для схемы борьбы с пиратством? –

+3

, вероятно, будет JNI-вызовом, ничего родного java – curtisk

+1

Да, это что-то вроде схемы борьбы с пиратством, чтобы идентифицировать компьютер. – Gohu

ответ

17

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

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

Java 6 Docs for Hardware Address

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

+4

Я думаю об этом, но когда сетевая карта не подключена, t получить любой MAC-адрес – Gohu

+0

Также возможно, чтобы пользователь мог переключать сетевые карты. На некоторых ноутбуках при выключении аккумулятора (проводная) карта Ethernet отключена для экономии заряда аккумулятора и, следовательно, не отображается в операционной системе. –

+3

И не забывайте, что даже не нужно менять сетевую карту, чтобы обмануть MAC: http://www.aboutlinux.info/2005/09/how-to-change-mac-address-of-your. html –

12

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

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

Чтобы получить идентификатор материнской платы или процессора, выполните следующие действия: link.

3

Я думаю, вы должны смотреть на этот link ... вы можете сделать смешанный ключ, используя несколько идентификаторов, таких как Mac OS + + имя хоста + cpu id + motherboard serial number.

+0

Ссылки, которые вы разместили за cpuid/moboserial, описывают способы, специфические для Windows. Это не кроссплатформенность. – BalusC

+1

В linux вы можете получить серийный номер hdd с помощью этой команды: hdparm -i/dev/sda1 | awk '/ SerialNo =/{print $ NF}' (просто узнайте ОС и попробуйте разные методы), вы можете найти серийный номер MB, используя команду lshw. –

+3

И не ожидайте, что антивирусы разрешат странные сценарии vbs, появляющиеся на вашем жестком диске. Большинство из них немедленно заблокируют файл, прежде чем у вас будет возможность его выполнить. –

9

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

Пример: (. Если вы хотите, чтобы исключить USB адаптеры)

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(); 
     } 
    } 
} 

И если вы решили использовать МАС-адрес для идентификации машины, вы можете использовать WMI, чтобы определить, подключен ли интерфейс через USB

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

7

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

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

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

6

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

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

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

22

Как альтернативный способ решения 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); 
    } 
} 
+3

Но как заставить его работать на MAC OS или Linux? – user584397

+0

Probaly нет единого способа получить уникальный идентификатор для MAC и Linux. Для Linux вы можете/sbin/udevadm получить серийный идентификатор http://serverfault.com/questions/305205/linux-hard-drive-serial-number-as-non-root – ozhan

+0

+1 от меня за лучшее решение, я использовал тот же подход, чтобы получить SN на ** [Linux] (https://github.com/sarxos/secure-tokens/blob/master/src/main/java/com/github/sarxos/securetoken/impl/Hardware4Nix. java) ** и ** [Mac OS] (https://github.com/sarxos/secure-tokens/blob/master/src/main/java/com/github/sarxos/securetoken/impl/Hardware4Mac.java) **, только команды и механизм синтаксического анализа различны. –

1

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

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

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

Тем не менее, нижеследующая ссылка является полезной для извлечения адресов mac. http://www.stratos.me/2008/07/find-mac-address-using-java/

39

Проблема с 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, доступен here:

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> 
    <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> 

выше конфигурация будет сказать плагин для создания классов в каталоге целевой/сгенерированные-источники/com4j в папке проекта.

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

+0

В Windows Nano Server 2016 формат «SerialNumber = xxx». Образец кода вернет когда-либо «=» в качестве серийного номера. На другой установке Windows это работает для меня. – Horcrux7

0

В программах ява я написал для выпуска Я использовал серийный номер материнской платы (это то, что я использую для использования Windows); однако это работает только с окнами, так как моя функция создает временный скрипт VB, который использует 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; 
     } 
0

Для однозначной идентификации машины для окон. Убедитесь, что вы используете wmic для стратегии альтернативных методов. Так как «Wmic биос получить 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/

19

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 

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

+1

Просто обратите внимание, что некоторые из этих операций требуют доступа root в зависимости от вашей ОС. Может быть ограничивающим фактором – user489041

Смежные вопросы