Comment obtenir un identifiant d'ordinateur unique en Java (comme ID de disque ou carte d'identité carte mère)?

StackOverflow https://stackoverflow.com/questions/1986732

  •  22-09-2019
  •  | 
  •  

Question

Je voudrais obtenir un identifiant unique à un ordinateur avec Java, sous Windows, MacOS et, si possible, Linux. Il pourrait être un UUID disque, carte mère S / N ...

Runtime.getRuntime().exec peut être utilisé (il est pas une applet).

Idées?

Était-ce utile?

La solution

Il est courant d'utiliser l'adresse MAC est associée à la carte réseau.

L'adresse est disponible en Java 6 à travers l'API suivante:

Java 6 Docs pour Adresse matérielle

Je ne l'ai pas utilisé en Java, mais pour d'autres applications d'identification de réseau, il a été utile.

Autres conseils

Le problème avec l'adresse MAC est qu'il peut y avoir de nombreux adaptateurs réseau connectés à l'ordinateur. La plupart des plus récents les ont deux par défaut (wi-fi + câble). Dans une telle situation, il faudrait savoir que l'adresse MAC de l'adaptateur doit être utilisé. Je testé la solution MAC sur mon système, mais j'ai 4 adaptateurs (câble, WiFi, adaptateur TAP pour Virtual Box et un pour Bluetooth) et je n'ai pas pu décider quel MAC je devrais prendre ... Si l'on décide de l'adaptateur utiliser qui est actuellement en cours d'utilisation (a des adresses) alors nouveau problème apparaît puisque quelqu'un peut prendre son / son ordinateur portable et passer de câble adaptateur pour wi-fi. Avec une telle condition MAC enregistrée un ordinateur portable a été connecté par le câble sera désormais invalide.

Par exemple ce sont des adaptateurs que j'ai trouvé dans mon système:

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

Je l'ai utilisé le code pour les énumérer:

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

Dans les options écouter sur cette page, la plus acceptable pour moi, et celui que je l'ai utilisé dans ma solution est celle par @Ozhan Duz, l'autre, semblable à @finnw réponse où il a utilisé JACOB, et à noter est com4j - échantillon qui utilise WMI est disponible :

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

imprimera des informations provenant de l'ordinateur avec l'ordinateur numéro de série. S'il vous plaît noter que toutes les classes requises par cet exemple doit être généré par maven-plugin-com4j. Exemple de configuration pour maven-plugin-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>

La configuration Above dire plug-in pour générer des classes dans le répertoire cible / généré sources / com4j dans le dossier du projet.

Pour ceux qui voudraient voir prêt à l'emploi solution, je suis avec des liens vers les trois classes que j'ai écrit pour obtenir la machine SN sous Windows, Linux et Mac OS:

  • Le OSHI projet fournit plate-forme indépendante Utilitaires hardware.

    dépendance Maven:

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

    Par exemple, vous pouvez utiliser quelque chose comme le code suivant pour identifier une machine unique:

    import oshi.SystemInfo;
    import oshi.hardware.CentralProcessor;
    import oshi.hardware.ComputerSystem;
    import oshi.hardware.HardwareAbstractionLayer;
    import oshi.software.os.OperatingSystem;
    
    class ComputerIdentifier
    {
        static String generateLicenseKey()
        {
            SystemInfo systemInfo = new SystemInfo();
            OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
            HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
            CentralProcessor centralProcessor = hardwareAbstractionLayer.getProcessor();
            ComputerSystem computerSystem = hardwareAbstractionLayer.getComputerSystem();
    
            String vendor = operatingSystem.getManufacturer();
            String processorSerialNumber = computerSystem.getSerialNumber();
            String processorIdentifier = centralProcessor.getIdentifier();
            int processors = centralProcessor.getLogicalProcessorCount();
    
            String delimiter = "#";
    
            return vendor +
                    delimiter +
                    processorSerialNumber +
                    delimiter +
                    processorIdentifier +
                    delimiter +
                    processors;
        }
    
        public static void main(String[] arguments)
        {
            String identifier = generateLicenseKey();
            System.out.println(identifier);
        }
    }
    

    Sortie pour ma machine:

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

    Votre sortie sera différente depuis au moins le processeur numéro de série différent.

Qu'est-ce que vous voulez faire avec cet ID unique? Peut-être que vous pouvez faire ce que vous voulez sans cet ID.

L'adresse MAC est peut-être une option, mais ce n'est pas un identifiant unique de confiance, car l'utilisateur peut changer l'adresse MAC d'un ordinateur.

Pour obtenir la carte mère ou processeur ID contrôle sur ce lien rel="noreferrer">.

Sur Windows uniquement, vous pouvez obtenir l'ID de la carte mère en utilisant WMI, à travers un pont de COM tel que JACOB .

Exemple:

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

Et si vous choisissez d'utiliser l'adresse MAC pour identifier la machine, vous pouvez utiliser WMI pour déterminer si une interface est connecté via USB (si vous voulez exclure des adaptateurs USB.)

Il est également possible d'obtenir un ID du disque dur via WMI, mais ce n'est pas fiable.

Soyez prudent lorsque vous utilisez l'adresse MAC comme un identifiant. Je l'ai connu plusieurs gotchas:

  1. Sur OS X, les ports Ethernet qui ne sont pas actifs / haut ne se présentent pas dans la section NetworkInterface.getNetworkInterfaces () Enumeration.
  2. Il est incroyablement facile de changer une adresse MAC sur les cartes si vous avez des privilèges d'OS appropriés.
  3. Java a l'habitude de ne pas identifier correctement les interfaces « virtuelles ». Même en utilisant la ( NetworkInterface.isVirtual) vous dira pas toujours la vérité.

Même avec les questions ci-dessus, je pense toujours que c'est la meilleure approche Java pur pour le matériel de verrouillage d'une licence.

Ne pas savoir à tous vos besoins. Par exemple, essayez-vous d'identifier un ordinateur à partir de tous les ordinateurs dans le monde, ou êtes-vous juste essayer d'identifier un ordinateur à partir d'un ensemble d'utilisateurs de votre application. En outre, vous pouvez créer des fichiers sur le système?

Si vous êtes en mesure de créer un fichier. Vous pouvez créer un fichier et utiliser le temps de création du fichier comme identifiant unique. Si vous créez dans l'espace utilisateur, il serait alors identifier de manière unique sur une machine particulière d'un utilisateur de votre application. Si vous l'avez créé, il pourrait alors quelque part globale identifier de manière unique la machine.

Encore une fois, comme la plupart des choses, comment est rapide assez vite .. ou dans ce cas, comment est assez unique, unique.

Je pense que vous devriez regarder ce lien ... vous pouvez faire une clé mixte utilisant plusieurs des identificateurs tels que Mac OS + + + nom d'hôte id cpu + carte mère le numéro de série .

L'utilisation de MAC id est le plus moyen plus facile si la tâche est de vous connecter l'identifiant unique d'un système.

le changement de MAC ID est cependant possible, même le changement d'autres identificateurs d'un système sont également possibles est que le dispositif respectif est remplacé.

, à moins que pour un identifiant unique est nécessaire est inconnu, nous ne pouvons pas être en mesure de trouver une solution appropriée.

Cependant, le lien ci-dessous est utile adresses MAC extraction. http://www.stratos.me/2008/07/ trouver-mac-address utilisant-java /

Pour identifier une machine à fenêtres unique. Assurez-vous que lorsque vous utilisez wmic d'avoir une stratégie de méthodes alternatives. Depuis « bios wmic se serialnumber » ne fonctionne pas sur toutes les machines, vous pourriez avoir besoin de disposer de méthodes supplémentaires:

# 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

Ressources: La meilleure façon pour identifier une machine Windows http://www.nextofwindows.com/ le mieux-way-unique-identifier-a-à-windows-linge /

Dans les programmes java j'ai écrit pour la libération j'ai utilisé le numéro de série mère (qui est ce que je beleive fenêtres utilisent); Cependant, cela ne fonctionne que sur les fenêtres que ma fonction crée un script VB temporaire qui utilise WMI pour récupérer la valeur.

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;
      }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top