2009-12-31 70 views
51

Me gustaría obtener una ID única para una computadora con Java, en Windows, MacOS y, si es posible, Linux. Podría ser un UUID de disco, placa madre s/n ...Cómo obtener un identificador único de computadora en Java (como ID de disco o ID de placa base)

Runtime.getRuntime().exec pueden utilizarse (no es un applet).

Ideas?

+1

¿Es esto para un plan antipiratería? –

+3

probablemente va a ser una llamada JNI, nada Java nativo – curtisk

+1

Sí, es para algo como el esquema antipiratería, para identificar una computadora. – Gohu

Respuesta

17

Es común usar la dirección MAC asociada con la tarjeta de red.

La dirección está disponible en Java 6 a través de las siguientes API:

Java 6 Docs for Hardware Address

No he utilizado en Java, pero para otras aplicaciones de identificación de red que ha sido de gran ayuda.

+4

Lo pienso, pero cuando la tarjeta de red no está conectada, puedo ' t obtener cualquier dirección MAC – Gohu

+0

También es posible que el usuario cambie las tarjetas de red. En algunas computadoras portátiles, cuando se agota la batería, la tarjeta Ethernet (con cable) se desactiva para ahorrar energía de la batería y, por lo tanto, no es visible para el sistema operativo. –

+3

Y no olvide que ni siquiera necesita cambiar la tarjeta de red para falsificar MAC: http://www.aboutlinux.info/2005/09/how-to-change-mac-address-of-your. html –

12

¿Qué desea hacer con esta identificación única? Tal vez puedas hacer lo que quieras sin esta identificación.

La dirección MAC puede ser una opción, pero esta no es una ID única de confianza porque el usuario puede cambiar la dirección MAC de una computadora.

Para obtener la placa base o la identificación del procesador, consulte este link.

3

creo que usted debe buscar en este link ... se puede hacer una llave mixta usando varios identificadores como Mac OS + + + nombre de host cpu id + motherboard serial number.

+0

Los enlaces que coloca detrás de cpuid/moboserial describen las formas específicas de Windows. Esto no es una plataforma cruzada. – BalusC

+1

en Linux puede obtener el número de serie del disco duro mediante este comando: hdparm -i/dev/sda1 | awk '/ SerialNo =/{print $ NF}' (simplemente reconoce el sistema operativo y prueba diferentes métodos) puedes encontrar el número de serie MB usando el comando lshw –

+3

Y no esperes que los antivirus activen las secuencias de comandos vbs extrañas que aparecen en tu disco duro. La mayoría de ellos bloqueará inmediatamente el archivo, antes de que tenga la oportunidad de ejecutarlo. –

9

En Windows solamente, puede obtener la ID de la placa madre usando WMI, a través de un puente COM como JACOB.

Ejemplo: (. Si desea excluir los adaptadores 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(); 
     } 
    } 
} 

Y si usted elige utilizar la dirección MAC para identificar la máquina, se puede utilizar WMI para determinar si una interfaz se conecta a través de USB

También es posible obtener una ID de disco duro a través de WMI, pero esto no es confiable.

7

Tenga cuidado al usar la dirección MAC como identificador. Yo he experimentado varias trampas:

  1. En OS X, puertos ethernet que no están activos/arriba no aparece en la enumeración NetworkInterface.getNetworkInterfaces().
  2. Es increíblemente fácil cambiar una dirección MAC en las tarjetas si tiene los privilegios adecuados del sistema operativo.
  3. Java tiene la costumbre de no identificar correctamente las interfaces "virtuales". Incluso el uso del NetworkInterface.isVirtual() no siempre te dirá la verdad.

Incluso con los problemas anteriores, sigo pensando que es el mejor enfoque puro de Java para el hardware que bloquea una licencia.

6

No se cumplen todos sus requisitos. Por ejemplo, ¿está tratando de identificar de forma única una computadora de todas las computadoras del mundo, o simplemente está tratando de identificar de manera única una computadora de un conjunto de usuarios de su aplicación? Además, ¿puedes crear archivos en el sistema?

Si puede crear un archivo. Puede crear un archivo y usar el tiempo de creación del archivo como su identificación única. Si lo crea en un espacio de usuario, identificaría de manera única a un usuario de su aplicación en una máquina en particular. Si lo creó en algún lugar global, podría identificar de manera única a la máquina.

Una vez más, como la mayoría de las cosas, qué tan rápido es lo suficientemente rápido ... o en este caso, lo único es lo suficientemente único.

22

Como una forma alternativa de la solución de finnw, la utilidad de línea de comandos wmic se puede usar para consultar los números de serie de los dispositivos. Sin dependencia externa, la mayoría de las cosas de WMI podrían establecerse con 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

¿Pero cómo hacer que funcione en MAC OS o Linux? – user584397

+0

De manera probal, no existe una forma única de obtener una identificación única para MAC y Linux. Para Linux, puede/sbin/udevadm obtener ID de serie http://serverfault.com/questions/305205/linux-hard-drive-serial-number-as-non-root – ozhan

+0

+1 de mi parte como la mejor solución, utilizó el mismo enfoque para activar SN ** [Linux] (https://github.com/sarxos/secure-tokens/blob/master/src/main/java/com/github/sarxos/securetoken/impl/Hardware4Nix. java) ** y ** [Mac OS] (https://github.com/sarxos/secure-tokens/blob/master/src/main/java/com/github/sarxos/securetoken/impl/Hardware4Mac.java) **, solo los comandos y el mecanismo de análisis son diferentes. –

1

El uso de MAC la identificación es más manera más fácil si la tarea se trata de registrar la identificación única de un sistema.

aunque es posible cambiar el ID de la mac, incluso el cambio de otras identificaciones de un sistema es que se reemplaza el dispositivo correspondiente.

por lo que, a menos que se desconozca qué se necesita para una identificación única, es posible que no podamos encontrar una solución adecuada.

Sin embargo, el siguiente enlace es útil para extraer direcciones mac. http://www.stratos.me/2008/07/find-mac-address-using-java/

39

El problema con la dirección MAC es que puede haber muchos adaptadores de red conectados a la computadora. La mayoría de los más nuevos tienen dos por defecto (wi-fi + cable). En tal situación, uno debería saber qué dirección MAC del adaptador debe usarse. Probé la solución MAC en mi sistema, pero tengo 4 adaptadores (cable, WiFi, adaptador TAP para Virtual Box y uno para Bluetooth) y no pude decidir qué MAC debería tomar ... Si uno decidiera usar un adaptador que está actualmente en uso (tiene direcciones asignadas), aparece un nuevo problema ya que alguien puede tomar su computadora portátil y cambiar el adaptador de cable a wi-fi. Con esa condición MAC almacenada cuando la computadora portátil estaba conectada a través de un cable, ahora no será válida.

Por ejemplo esos son los adaptadores que encontré en mi sistema:

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 

Código he utilizado para listarlos:

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

En las opciones de escuchar en esta página, la más aceptable para yo, y el que he usado en mi solución es el de @Ozhan Duz, el otro, similar a la respuesta @finnw donde usó JACOB, y vale la pena mencionar es com4j - muestra que hace uso de WMI está disponible 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)); 
} 

Esto imprimirá información de la computadora junto con el número de serie de la computadora. Tenga en cuenta que todas las clases requeridas por este ejemplo deben ser generadas por maven-com4j-plugin. Ejemplo de configuración para el experto-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> 

configuración de encima le dirá Plugin para generar clases en el directorio de destino/Fuentes generadas/com4j en la carpeta del proyecto.

Para aquellos que les gustaría ver listos para su uso solución, estoy incluyendo enlaces a las tres clases que escribí para obtener SN máquina en Windows, Linux y Mac OS:

+0

En Windows Nano Server 2016, el formato es "SerialNumber = xxx". El código de muestra devolverá siempre "=" como número de serie. En otra instalación de Windows, funciona para mí. – Horcrux7

0

En los programas Java que he escrito para la liberación Utilicé el número de serie de la placa madre (que es lo que creo que usan las ventanas); sin embargo, esto solo funciona en Windows ya que mi función crea un script temporal de VB que usa WMI para recuperar el valor.

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

Para identificar una máquina de Windows únicamente. Asegúrese de utilizar wmic para tener una estrategia de métodos alternativos. Desde "bios wmic consiguen número de serie" podría no funcionar en todas las máquinas, puede que tenga que tener métodos adicionales:

# 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 

Recursos: la mejor manera de identificar de forma única una máquina Windows http://www.nextofwindows.com/the-best-way-to-uniquely-identify-a-windows-machine/

19

El proyecto OSHI proporciona utilidades de hardware independientes de la plataforma.

Maven dependencia:

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

Por ejemplo, se podría utilizar algo como el siguiente código para identificar una máquina única:

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

salida para mi máquina:

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

Su salida será diferente ya que al menos el número de serie del procesador será diferente.

+1

Solo para tener en cuenta, algunas de estas operaciones requieren acceso raíz en función de su sistema operativo. Podría ser un factor limitante – user489041

Cuestiones relacionadas