Nice programing

Java에서 고유 한 컴퓨터 식별자 (예 : 디스크 ID 또는 마더 보드 ID)를 얻는 방법은 무엇입니까?

nicepro 2020. 12. 7. 20:38
반응형

Java에서 고유 한 컴퓨터 식별자 (예 : 디스크 ID 또는 마더 보드 ID)를 얻는 방법은 무엇입니까?


Java, Windows, MacOS 및 가능하면 Linux (가능한 경우)가있는 컴퓨터에 고유 한 ID를 얻고 싶습니다. 디스크 UUID, 마더 보드 S / N ...

Runtime.getRuntime().exec 사용할 수 있습니다 (애플릿이 아님).

아이디어?


네트워크 카드와 연결된 MAC 주소를 사용하는 것이 일반적입니다.

이 주소는 다음 API를 통해 Java 6에서 사용할 수 있습니다.

하드웨어 주소 용 Java 6 문서

Java에서는 사용하지 않았지만 다른 네트워크 식별 응용 프로그램에서는 도움이되었습니다.


MAC 주소의 문제는 컴퓨터에 많은 네트워크 어댑터가 연결되어있을 수 있다는 것입니다. 대부분의 최신 제품에는 기본적으로 2 개 (wi-fi + 케이블)가 있습니다. 이러한 상황에서는 어떤 어댑터의 MAC 주소를 사용해야하는지 알아야합니다. 시스템에서 MAC 솔루션을 테스트했지만 4 개의 어댑터 (케이블, WiFi, Virtual Box 용 TAP 어댑터, Bluetooth 용 어댑터 1 개)가 있고 어떤 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의 하나이며 다른 하나는 JACOB를 사용한 @finnw 대답과 유사하며 언급할만한 가치가 있습니다. 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 디렉토리에 클래스를 생성하도록 플러그인에 지시합니다.

즉시 사용할 수있는 솔루션 을보고 싶은 사람들 을 위해 Windows, Linux 및 Mac OS에서 시스템 SN을 얻기 위해 작성한 세 가지 클래스에 대한 링크를 포함했습니다.


OSHI프로젝트는 플랫폼 독립적 인 하드웨어 유틸리티를 제공합니다 .

Maven 종속성 :

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

예를 들어, 다음 코드와 같은 것을 사용하여 기계를 고유하게 식별 할 수 있습니다.

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

내 컴퓨터에 대한 출력 :

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

적어도 프로세서 일련 번호가 다르기 때문에 출력이 달라집니다.


이 고유 ID로 무엇을 하시겠습니까? 이 ID 없이도 원하는 것을 할 수 있습니다.

MAC 주소는 하나의 옵션 일 수 있지만 사용자가 컴퓨터의 MAC 주소를 변경할 수 있기 때문에 신뢰할 수있는 고유 ID가 아닙니다.

To get the motherboard or processor ID check on this link.


On Windows only, you can get the motherboard ID using WMI, through a COM bridge such as JACOB.

Example:

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

And if you choose to use the MAC address to identify the machine, you can use WMI to determine whether an interface is connected via USB (if you want to exclude USB adapters.)

It's also possible to get a hard drive ID via WMI but this is unreliable.


Be careful when using the MAC address as an identifier. I've experienced several gotchas:

  1. On OS X, ethernet ports that are not active/up do not show up in the NetworkInterface.getNetworkInterfaces() Enumeration.
  2. It's insanely easy to change a MAC address on cards if you've got appropriate OS privileges.
  3. Java has a habit of not correctly identifying "virtual" interfaces. Even using the NetworkInterface.isVirtual() won't always tell you the truth.

Even with the above issues, I still think it's the best pure Java approach to hardware locking a license.


Not Knowing all of your requirements. For example, are you trying to uniquely identify a computer from all of the computers in the world, or are you just trying to uniquely identify a computer from a set of users of your application. Also, can you create files on the system?

If you are able to create a file. You could create a file and use the creation time of the file as your unique id. If you create it in user space then it would uniquely identify a user of your application on a particular machine. If you created it somewhere global then it could uniquely identify the machine.

Again, as most things, How fast is fast enough.. or in this case, how unique is unique enough.


I think you should look at this link ... you can make a mixed key using several identifiers such as mac+os+hostname+cpu id+motherboard serial number.


The usage of MAC id is most easier way if the task is about logging the unique id a system.

the change of mac id is though possible, even the change of other ids of a system are also possible is that respective device is replaced.

so, unless what for a unique id is required is not known, we may not be able to find an appropriate solution.

However, the below link is helpful extracting mac addresses. http://www.stratos.me/2008/07/find-mac-address-using-java/


For identifying a windows machine uniquely. Make sure when you use wmic to have a strategy of alternative methods. Since "wmic bios get serialnumber" might not work on all machines, you might need to have additional methods:

# 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

Resources: The Best Way To Uniquely Identify A Windows Machine http://www.nextofwindows.com/the-best-way-to-uniquely-identify-a-windows-machine/


In the java programs I have written for release I used the motherboard serial number (which is what I beleive windows use); however, this only works on windows as my function creates a temporary VB script which uses the WMI to retrieve the value.

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

참고URL : https://stackoverflow.com/questions/1986732/how-to-get-a-unique-computer-identifier-in-java-like-disk-id-or-motherboard-id

반응형