如何在Java中获取CPU-ID?

8

我希望使用Java创建一个加密程序。
有没有任何方式可以获取PC上唯一的CPU ID或类似BIOS的东西...

例如,System.getCpuId();只是一个示例。

非常感谢...


不,你知道为什么吗?因为我想获取CPUID,然后生成一个代码,然后用户将其(生成的代码)发送给我,我再发送激活码给他们... - Freeman
所以这真的是一种数字版权管理方案吗? - Matthew Flaschen
请注意,如果您的软件将在互联网上提供下载,黑客将会简单地删除您的代码中检查激活密钥与CPU ID匹配部分。 - Steve McLeod
1
@PeanutPower,不适合用于复制保护目的,因为只需复制文件和注册表项即可在另一台机器上复制。主板ID也可以伪造,但需要更多的努力。 - finnw
6
啊,又来一个许可证管理器。这会让你付出比收入更多的汗水、鲜血和眼泪。 - Thorbjørn Ravn Andersen
显示剩余3条评论
7个回答

5

所以您想要一个唯一的数字(或字符串?)来标识用户的计算机?或者至少是足够唯一,重复的几率非常低,对吧?

您可以获取网络接口的Mac地址。这样做会有很多假设,但可能已经足够满足您的需求:

final byte[] address = NetworkInterface.getNetworkInterfaces().nextElement().getHardwareAddress();
System.out.println("address = " + Arrays.toString(address));

这将给你一个字节数组。你可以通过多种方式将其转换为id,比如十六进制字符串。

但是要注意,在人们更换计算机硬件的时候,需要进行支持。


2
这可以很容易地改变 (http://www.topbits.com/how-to-change-a-mac-address.html) - Matthew Flaschen
1
这是我所做的许多假设之一!如今几乎每台计算机都已联网,因此都有网络接口卡(NIC)。但根据您的需求,这可能不是一个好的假设... - Steve McLeod
1
我之前使用过某些软件,真的很、很烦人。我在家中使用有线连接安装该软件,但当我改用无线连接时就无法使用了。虽然我知道可以在网络连接中重新排列网络设备,但这很麻烦。 - ericp
MAC地址可以很容易地更改。它不应该在同一网络中运行两台机器。 - SaidbakR
我尝试使用这种方法,但遇到了那些在认为自己不需要网络访问时禁用其网络访问的用户。问题在于,每当发生这种情况时,MAC地址就会“消失”... - Melvin

4

我认为Java中没有这样的特定于操作系统的命令。

这个链接展示了在Windows上运行它的方法。


这实际上非常聪明!应该将它移植到其他环境中,并将其打包成一个库。 - Joonas Pulakka
好的,Linux(我相信OS X也是如此)有像dmesg和uname这样的命令,以及像/proc/cpuinfo这样的位置,可以提供各种与硬件相关的信息。因此,只需要使用System.exec运行相关命令并解析它们的输出即可。当然,很难保证某些特定信息可用(或者它是否正确),但至少可以尝试一下。 - Joonas Pulakka
这个特定的命令可能是与架构相关的,而不是操作系统相关的 - 例如,CPUID指令和相关指令。话虽如此,这可能会在x86上运行,所以我通常不认为这是一个大问题。 - poundifdef
这是根据问题最接近正确答案的回答。 - Neil Benn

3
您不能在纯Java中可靠地获取硬件信息。 您必须使用JNAJNI。您能否澄清您正在构建什么类型的加密系统,以及为什么需要硬件信息?
编辑:Steve McLeod指出Java有一个NetworkInterface.getHardwareAddress()方法。 但是,存在严重的注意事项,包括并非所有Java实现都允许访问它,并且MAC地址可以轻松伪造。

并不完全准确,因为java.net.NetworkInterface 类能够证明这一点。 - President James K. Polk
你说得没错。但请注意,并非所有的实现都支持这种方法(请参见http://java.sun.com/javase/6/docs/api/java/net/NetworkInterface.html#getHardwareAddress%28%29),并非所有计算机都有网络卡,人们经常更换网络卡(例如从有线到无线),而且很容易伪造地址。考虑到这些因素,我认为这是一条死路。 - Matthew Flaschen

2
你还需要考虑一台机器可能具有多个CPU / NIC或其他硬件,因此会有多个ID。

1

如果您需要唯一的ID,可以使用UUID

import java.util.UUID;

public class GenerateUUID {


      public static final void main(String... aArgs){
        //generate random UUIDs
        UUID idOne = UUID.randomUUID();
        UUID idTwo = UUID.randomUUID();
        log("UUID One: " + idOne);
        log("UUID Two: " + idTwo);
      }

      private static void log(Object aObject){
        System.out.println( String.valueOf(aObject) );
      }
    } 

示例运行:

>java -cp . GenerateUUID
UUID One: 067e6162-3b6f-4ae2-a171-2470b63dff00 
UUID Two: 54947df8-0e9e-4471-a2f9-9af509fb5889

UUID 的确切含义是什么? - Freeman
UUID在JAVA中是唯一的,并且用于需要通用唯一标识符的字段。 - Sajad Bahmani
2
@Mike Redford:当然,一些应用程序使用UUID。它是通用的 :-) - Sajad Bahmani
你需要在本地存储生成的 UUID,以便稍后匹配发送的激活码。一个有决心的用户可以轻松绕过这个限制。 - Steve McLeod
6
我认为发帖者希望得到一个稳定的标识符(即该计算机上的标识符将保持不变),并且很难伪造。 - finnw
海报被要求提供CPU ID而不是UUID。 - Neil Benn

1

在Java中,没有直接获取硬件信息的方法,除非使用一些JNA/JNI库。话虽如此,您可以使用System.getEnv()获取“某种程度上独特的、系统特定的值”。例如:

System.getEnv("COMPUTERNAME")

应该返回Windows系统中计算机的名称。当然,这是高度不可移植的。而且在同一系统中,这些值可能会随时间变化。或者在不同的系统中是相同的。哦,好吧...


1
你可以在不使用JNI的情况下获取MAC地址,顺便说一下。 - finnw

0

用户想要的是CPU ID而不是随机数。 - Neil Benn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接