C#基于硬件ID创建唯一标识

12

我正在创建一种仅适用于特定机器的许可证。该许可证基于以下项目:

  1. MAC地址
  2. CPU序列号
  3. 驱动器0的计算机卷序列号

我认为如果其中2个匹配,则我的许可证就是有效的。因此,用户可以更换网络卡,并且许可证仍然有效等。

这是一个好方法吗?还是说会出现无法匹配或者经常变化的问题?

我试图获取计算机的唯一标识符,以便验证许可证。

请告诉我您对此的看法,或者是否有更好的解决方案!

谢谢!

** 以下是我想到的方案 **

我最终只使用了VolumeSerial、CpuId和VideoControllerDescription。

    public enum HardwareProfileComponents
    {
        ComputerModel,
        VolumeSerial,
        CpuId,
        MemoryCapacity,
        VideoControllerDescription
    }

    public static Dictionary<string, string> HardwareProfile()
    {
        var retval = new Dictionary<string, string>
                         {
                             {HardwareProfileComponents.ComputerModel.ToString(), GetComputerModel()},
                             {HardwareProfileComponents.VolumeSerial.ToString(), GetVolumeSerial()},
                             {HardwareProfileComponents.CpuId.ToString(), GetCpuId()},
                             {HardwareProfileComponents.MemoryCapacity.ToString(), GetMemoryAmount()},
                             {HardwareProfileComponents.VideoControllerDescription.ToString(), GetVideoControllerDescription()}
                         };
        return retval;

    }

    private static string GetVideoControllerDescription()
    {
        Console.WriteLine("GetVideoControllerDescription");

        var s1 = new ManagementObjectSearcher("select * from Win32_VideoController");
        foreach (ManagementObject oReturn in s1.Get())
        {
            var desc = oReturn["AdapterRam"];
            if ( desc == null) continue;
            return oReturn["Description"].ToString().Trim();
        }
        return string.Empty;
    }


    private static string GetComputerModel()
    {
        Console.WriteLine("GetComputerModel");
        var s1 = new ManagementObjectSearcher("select * from Win32_ComputerSystem"); 
        foreach (ManagementObject oReturn in s1.Get())
        {
            return oReturn["Model"].ToString().Trim();
        }            
        return string.Empty;
    }

    private static string GetMemoryAmount()
    {
        Console.WriteLine("GetMemoryAmount");
        var s1 = new ManagementObjectSearcher("select * from Win32_PhysicalMemory");
        foreach (ManagementObject oReturn in s1.Get())
        {
            return oReturn["Capacity"].ToString().Trim();
        }
        return string.Empty;
    }

    private static string GetVolumeSerial()
    {
        Console.WriteLine("GetVolumeSerial");
        var disk = new ManagementObject(@"win32_logicaldisk.deviceid=""c:""");
        disk.Get();

        string volumeSerial = disk["VolumeSerialNumber"].ToString();
        disk.Dispose();

        return volumeSerial;
    }

    private static string GetCpuId()
    {
        Console.WriteLine("GetCpuId");
        var managClass = new ManagementClass("win32_processor");
        var managCollec = managClass.GetInstances();

        foreach (ManagementObject managObj in managCollec)
        {
            //Get only the first CPU's ID
            return managObj.Properties["processorID"].Value.ToString();
        }
        return string.Empty;
    }

首先,这是不可能的 - GUID 是一种特定计算的 UUID,因此使用术语 GUID 本身就定义了它基于特定的计算形式。 - TomTom
我更改了标题,避免称其为“GUID”,因为正如@TomTom所指出的那样,那是一种特定类型的ID。 - Edward Thomson
@ivowiblo:这可以做到——也就是说,您可以创建一个唯一标识计算机的数字或字符串,但这不会成为GUID,根据定义。http://en.wikipedia.org/wiki/Globally_unique_identifier - Edward Thomson
哦!我没有看到之前的标题。 - Ivo
3个回答

14
并非真正的答案,而是一个警告。我曾经在一家软件公司工作,他们有一个类似的许可机制,但是...它很脆弱。特别是在笔记本电脑上。请考虑以下问题:
1. 在笔记本电脑上在有线和无线之间切换时,每个接口上的MAC地址都不同。
2. 更改MAC地址可能会有优点。例如,在美国,一些有线互联网提供商愚蠢地将您的MAC地址与您的帐户绑定,如果路由器出现故障,则需要直接将计算机插入有线电缆调制解调器,然后克隆其路由器的MAC地址。
3. 如果用户从不同的硬盘(例如闪存驱动器或USB闪存驱动器)启动,这是否会更改报告的第一个驱动器?
而当时这还远在商品化虚拟化之前。现在,请考虑您可以切换设置并重新启动VM,从而具有:不同数量的RAM、不同大小的硬盘、不同类型的虚拟硬盘控制器类型(IDE、SCSI,甚至多个SCSI控制器接口)。您可以使用鼠标轻松交换CD / DVD设备,并更改NIC设置。
因此,我并不是说“不要这样做”,但我会鼓励您在尽可能多的环境中在尽可能多的机器上测试此机制,我还将建议您:当用户无法运行他们已经付款的软件时,他们的耐心非常有限。
您考虑过硬件加密狗吗?

我打印了这个并与程序员讨论了一下,我的老板希望我们看看我能够对通常不会改变的项目做些什么。我只能为一个选票投票,但我确实给了你一个好答案和需要注意的事项的标记。 - ErocM

9

我发现现在检查MAC地址并没有多大意义。每台计算机都有一个以上的网络适配器,其中任何一个都可能是可能存在或不存在的外部设备。我们几年前推出了一个过于关注MAC地址的系统,结果导致了客户服务的灾难。

另一方面,更换CPU、主板、总线/磁盘控制器或主硬盘相对较少。


MAC地址的评论非常好。我完全同意。我的笔记本电脑有一个可拆卸的网络适配器,但它断了。因此,我正在使用CPU序列号和硬盘序列号(基于C驱动器)。当我尝试获取主板序列号时,在我测试的一半计算机上回传空白值。你也是这样吗? - ErocM
CPU、主板、总线/磁盘控制器等这些序列号要么相同,要么为空...有人遇到过同样的问题吗? - amarnath chatterjee

8

这是一篇关于微软如何在Windows XP中实现激活的不错文章。虽然可能不完全符合你的要求,但它是一个很好的起点。

解释了Windows XP激活

Windows检查哪些硬件?

系统会检查以下十个硬件类别:

  • 显示适配器
  • SCSI适配器
  • IDE适配器(实际上是主板)
  • 网络适配器(NIC)及其MAC地址
  • RAM容量范围(即0-64MB,64-128MB等)
  • 处理器类型
  • 处理器序列号
  • 硬盘设备
  • 硬盘卷序列号(VSN)
  • CD-ROM / CD-RW / DVD-ROM

这给了我我所需要的东西。更多的是一份实用清单,我可以使用它们。我将选择那些在特定日子里通常不会改变的项目。谢谢! - ErocM
没问题。我很高兴能够帮忙。顺便说一下 - 我也在研究同样的问题。在阅读其他评论和答案之后,我相信我会“跳过”网卡 MAC 地址。Edward 和 Sean 在这方面都提供了明智的建议。 - Wesley Long

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