Java 获取已断开连接的卡的 mac 地址

2022-09-03 02:49:06

我想获取以太网卡的MAC(用于产品密钥),我尝试使用这种解决方案并在此处搜索,问题是当所有网络断开连接(以太网和wifi)时,它会返回空MAC地址。我宁愿得到以太网的地址,即使它断开连接。

谢谢!!

   public static void main(String[] args)
    {
        InetAddress ip;
        try {
            ip = InetAddress.getLocalHost();

            System.out.println("The mac Address of this machine is :" + ip.getHostAddress());

            NetworkInterface network = NetworkInterface.getByInetAddress(ip);

            byte[] mac = network.getHardwareAddress();

            System.out.print("The mac address is : ");

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < mac.length; i++){
                sb.append(String.format("%02X%s", mac[i],(i< mac.length - 1)?"-":""));
            }

            System.out.println(sb.toString());

        } 
        catch (UnknownHostException e) {
            e.printStackTrace();
        } 
        catch (SocketException e) {
            e.printStackTrace();
        }
    }
}

答案 1

使用绑定可以查看 IP 地址列表。如果由于接口全部断开连接而没有,则无法循环访问此类接口。InetAddress

你应该尝试上课。NetworkInterface

public class MacAddressTest
{
  public static void main(String[] args) throws Exception
  {
    Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();

    while (interfaces.hasMoreElements())
    {
      NetworkInterface nif = interfaces.nextElement();
      byte[] lBytes = nif.getHardwareAddress();
      StringBuffer lStringBuffer = new StringBuffer();

      if (lBytes != null)
      {
        for (byte b : lBytes)
        {
          lStringBuffer.append(String.format("%1$02X ", new Byte(b)));
        }
      }

      System.out.println(lStringBuffer);
    }
  }
}

答案 2

如果您希望使用一些唯一的硬件标识符来验证许可证,那么我建议您使用OSHI(操作系统和硬件信息)来获取所需的硬件信息。

一般主体是将硬件标识符编码为客户端许可证字符串,然后在客户端运行时,它将从许可证字符串中解码该 ID,并确保存在硬件以验证许可证。不要依赖索引,因为通常不能保证硬件顺序,只需循环访问有问题的硬件列表,然后查看密钥绑定到的硬件是否存在。

注意:当许可证验证在本地完成时,它总是可以被破解;重点只是为了让它变得烦人。如果您的许可证本身只是普通的MAC地址,那么人们很容易查找他们的MAC并为自己提供有效的许可证。即使您将MAC编码/加密到许可证中,他们也可以查看反编译的代码并找到解码(以及因此编码)的工作原理,以便他们可以对自己的有效许可证进行编码。您需要尽可能多地加密和混淆,以使人们难以生成自己的许可证,但最终它只会使破解起来更烦人,但并非不可能。

除了 MAC 地址之外,另一个选项是绑定到磁盘。磁盘序列号不像 MAC 地址那样容易更改。有了这个,您可以将许可证绑定到USB密钥,这有点有趣。唯一需要担心的是人们更换磁盘,但如果软件许可证绑定到它存储的磁盘上,那么这几乎不是问题。

啪.xml

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

客户端许可证.java

import oshi.SystemInfo;
import oshi.hardware.HWDiskStore;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.NetworkIF;

/**
 * This class would be loaded with the client license and validate that the license is for the machine running this code.
 */
public class ClientLicense {
    final String clientLicenseString;

    public ClientLicense(String clientLicenseString) {
        this.clientLicenseString = clientLicenseString;
    }

    public final boolean validateByDisk() {
        int expectedModelSerialHash = decodeExpectedModelSerialHash(clientLicenseString);
        for (HWDiskStore disk : new SystemInfo().getHardware().getDiskStores()) {
            if (expectedModelSerialHash == Objects.hash(disk.getModel(), disk.getSerial())) {
                return true;
            }
        }
        return false;
    }

    public final boolean validateByMAC() {
        String expectedMac = decodeExpectedMac(clientLicenseString);
        for (NetworkIF netIF : new SystemInfo().getHardware().getNetworkIFs()) {
            if (expectedMac.equals(netIF.getMacaddr())) {
                return true;
            }
        }
        return false;
    }

    private int decodeExpectedModelSerialHash(String clientLicenseString) {
        // obfuscate license decoding, inverse of license encoding/encrypting
        return 0; // return the expected hash of model and serial
    }

    private String decodeExpectedMac(String clientLicenseString) {
        // obfuscate license decoding, inverse of license encoding/encrypting
        return ""; // return the expected MAC address
    }
}

或者,您可以在此示例文件中看到许多硬件信息。


此外,请参阅oshi-demo中的示例类(如Daniel Widdis所提到的);该示例包含以下方法:ComputerID.java

/**
 * Generates a Computer Identifier, which may be part of a strategy to
 * construct a licence key. (The identifier may not be unique as in one case
 * hashcode could be same for multiple values, and the result may differ
 * based on whether the program is running with sudo/root permission.) The
 * identifier string is based upon the processor serial number, vendor,
 * processor identifier, and total processor count.
 * 
 * @return A string containing four hyphen-delimited fields representing the
 *         processor; the first 3 are 32-bit hexadecimal values and the last
 *         one is an integer value.
 */
public static String getComputerIdentifier() {
    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 String.format("%08x", vendor.hashCode()) + delimiter
            + String.format("%08x", processorSerialNumber.hashCode()) + delimiter
            + String.format("%08x", processorIdentifier.hashCode()) + delimiter + processors;
}

推荐