真的有什么方法可以唯一地识别任何一台计算机吗

本文关键字:任何一 识别 计算机 唯一 什么 方法 真的 | 更新日期: 2023-09-27 18:26:05

我知道stackoverflow中有很多类似的问题,例如:

  • 唯一识别计算机的好方法是什么
  • 什么是好的唯一PC标识符
  • 唯一计算机id C#
  • WIN32_Processor::所有计算机的ProcessorId是否唯一
  • 如何使用C#唯一识别计算机

还有几十个,我都研究过了。

问题是,一些公认的答案建议MAC地址作为唯一标识符,这是完全不正确的。其他一些答案建议使用各种组件的组合,这似乎更合乎逻辑。然而,在使用组合的情况下,应该考虑哪个组件自然不太可能频繁更改。几天前,我们为一个软件许可问题开发了一个密钥生成器,我们使用CPUID和MAC的组合来唯一地识别windows pc,直到进行实际测试,我们认为我们的方法已经足够好了。具有讽刺意味的是,当我们测试它时,我们发现三台计算机返回了与我们的密钥生成器相同的id!

那么,真的有什么方法可以唯一地识别任何计算机吗?现在我们只需要让我们的密钥生成器在windows pc上工作。某种方式(如果可能的话)使用c#将是很棒的,因为我们的系统是在.net上开发的。

更新:

很抱歉造成了一些混乱和明显的虚惊一场。我们在检索硬件信息的方法中发现了一些错误。我最初想删除这个问题,因为现在我自己的困惑已经消失了,我确实相信两个或多个组件的组合足以识别一台计算机。然而,后来我决定保留它,因为我认为我应该澄清问题的原因,因为同样的事情可能会在未来伤害其他人。

这就是我们正在做的(不包括其他代码):

我们使用getManagementInfo函数来检索MAC和处理器ID

private String getManagementInfo(String StrKey_String, String strIndex)
    {
        String strHwInfo = null;
        try
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from " + StrKey_String);
            foreach (ManagementObject share in searcher.Get())
            {
                strHwInfo += share[strIndex];
            }
        }
        catch (Exception ex)
        {
            // show some error message
        }
        return strHwInfo;
    } 

然后在需要的地方,我们使用该功能来检索MAC地址

string strMAC = getManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress");

并检索ProcessorID

string strProcessorId = getManagementInfo("Win32_Processor", "ProcessorId");

此时,如果存在不止一个MAC地址,则strMAC将包含不止一个。为了只取一个,我们只取了前17个字符(12个MAC数字和中间的5个冒号)。

strMAC = strMAC.Length > 17 ? strMAC.Remove(17) : strMAC;

这就是我们犯错误的地方。因为getManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress")返回了许多实际使用中的额外MAC地址。例如,当我们通过getmac命令在命令提示符中搜索MAC地址时,它会为每台电脑显示一到两个不同的MAC地址。但getManagementInfo("Win32_NetworkAdapterConfiguration", "MacAddress")返回了四到五个MAC地址,其中一些地址对于所有计算机都是相同的。由于我们只是获取函数返回的第一个MAC地址,而不是检查其他任何内容,因此strMAC中偶然获取了相同的MAC地址。

Sowkot Osman的以下代码只返回第一个活动/启用的MAC地址:

private static string macId()
    {
        return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
    }
private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue)
    {
        string result = "";
        System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
        System.Management.ManagementObjectCollection moc = mc.GetInstances();
        foreach (System.Management.ManagementObject mo in moc)
        {
            if (mo[wmiMustBeTrue].ToString() == "True")
            {
                //Only get the first one
                if (result == "")
                {
                    try
                    {
                        result = mo[wmiProperty].ToString();
                        break;
                    }
                    catch
                    {
                    }
                }
            }
        }
        return result;
    }
    //Return a hardware identifier
    private static string identifier(string wmiClass, string wmiProperty)
    {
        string result = "";
        System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
        System.Management.ManagementObjectCollection moc = mc.GetInstances();
        foreach (System.Management.ManagementObject mo in moc)
        {
            //Only get the first one
            if (result == "")
            {
                try
                {
                    result = mo[wmiProperty].ToString();
                    break;
                }
                catch
                {
                }
            }
        }
        return result;
    }

然而,对于相同的处理器ID问题,我是绝对正确的。当我们在它们的命令提示符中放入wmic cpu get ProcessorId命令时,这三个都返回了相同的处理器ID。

现在我们决定使用主板序列号而不是处理器ID来与MAC地址进行组合。我认为我们的目标会以这种方式实现,如果在某些情况下没有实现,那么在少数情况下我们应该放手。

真的有什么方法可以唯一地识别任何一台计算机吗

添加主板序列号怎么样,例如:

using System.management;

//Code for retrieving motherboard's serial number
ManagementObjectSearcher MOS = new ManagementObjectSearcher("Select * From Win32_BaseBoard");
foreach (ManagementObject getserial in MOS.Get())
{
textBox1.Text = getserial["SerialNumber"].ToString();
}
//Code for retrieving Processor's Identity
MOS = new ManagementObjectSearcher("Select * From Win32_processor");
foreach (ManagementObject getPID in MOS.Get())
{
textBox2.Text = getPID["ProcessorID"].ToString();
}
//Code for retrieving Network Adapter Configuration
MOS = new ManagementObjectSearcher("Select * From Win32_NetworkAdapterConfiguration");
foreach (ManagementObject mac in MOS.Get())
{
textBox3.Text = mac["MACAddress"].ToString();
}

获取全局唯一ID的事实是,只有MAC地址是在您全面设置系统时不会更改的ID。如果您要为特定产品生成密钥,最好的方法是为产品分配唯一的ID,并将产品ID与MAC地址相结合。希望能有所帮助。

我完全同意上述评论。

对于软件许可,您可以使用:

计算机MAC地址(如果有多个NIC卡,则取所有)+您的软件产品代码

大多数著名的电信供应商都在使用这种技术。

然而,我对相同的处理器ID是绝对正确的问题当我们放置wmic cpu时,这三个都返回了相同的处理器IDgetProcessorId命令。

如果所有系统都作为虚拟机在同一个系统管理程序上运行,则处理器ID将相同。

MAC ID似乎很好。唯一的问题是必须为用户提供重置应用程序的选项,以防MAC发生更改。

看起来定制厨房就是这样。

SMBIOS UUID(主板串行)并不健壮,但在99%的情况下都能正常工作。然而,一些品牌会为多台计算机设置相同的UUID(可能是同一生产批次)。获取它需要用户(如果他不是管理员)的WMI访问权限,您可以通过启动一个外部进程询问管理员权限来解决这个问题(请查看codeproject.com/Articles/15848/WMI命名空间安全)

Windows产品ID可能不错,但我读到它在某些情况下可能是相同的(https://www.nextofwindows.com/the-best-way-to-uniquely-identify-a-windows-machine)有人能澄清多台计算机上是否存在相同的产品ID(而不是产品密钥)吗?

HKEY_LOCAL_MACHINE''SOFTWARE''Microsoft''Cryptography''MachineGuid似乎很有趣。它是在安装Windows时生成的,如果更改,则需要重新激活Windows。

Mac地址正在插入测试,但您只能使用第一个地址,或者当接口被禁用时,或者当添加另一个网络接口并首先出现时,您的唯一ID将更改。

硬盘驱动器序列号很好,但当安装重影时,它也可能会覆盖原始驱动器的序列号。。。而且HD系列非常容易更改。

最好的方法是用这些机器标识符的组合生成一个ID,并通过比较这些标识符来决定机器是否相同(即,如果至少有一个Mac地址+SMBIOS UUID或产品ID可以,则接受)

相关文章: