【问题标题】:Why is my ID changing with internet connectivity?为什么我的 ID 会随着互联网连接而改变?
【发布时间】:2018-02-25 13:04:57
【问题描述】:

我关注this tutorial 为系统生成唯一的硬件 ID。问题是联网时生成的ID不一样,断网时生成的ID也不一样。

这是我正在使用的代码:

    private static string fingerPrint = string.Empty;
    public static string GetUniqueID()
    {
        if (string.IsNullOrEmpty(fingerPrint))
        {
            fingerPrint = GetHash("CPU " + cpuId() + "\nBIOS " + 
                biosId() + "\nBASE " + baseId()
                + "\nVIDEO " + videoId() +"\nMAC "+ macId()
            );
        }
        return fingerPrint;
    }
    private static string GetHash(string s)
    {
        MD5 sec = new MD5CryptoServiceProvider();
        ASCIIEncoding enc = new ASCIIEncoding();
        byte[] bt = enc.GetBytes(s);
        return GetHexString(sec.ComputeHash(bt));
    }
    private static string GetHexString(byte[] bt)
    {
        string s = string.Empty;
        for (int i = 0; i < bt.Length; i++)
        {
            byte b = bt[i];
            int n, n1, n2;
            n = (int)b;
            n1 = n & 15;
            n2 = (n >> 4) & 15;
            if (n2 > 9)
                s += ((char)(n2 - 10 + (int)'A')).ToString();
            else
                s += n2.ToString();
            if (n1 > 9)
                s += ((char)(n1 - 10 + (int)'A')).ToString();
            else
                s += n1.ToString();
            if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-";
        }
        return s;
    }

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

    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)
        {
            if (result == "")
            {
                try
                {
                    result = mo[wmiProperty].ToString();
                    break;
                }
                catch
                {
                }
            }
        }
        return result;
    }
    private static string cpuId()
    {
        string retVal = identifier("Win32_Processor", "UniqueId");
        if (retVal == "")
        {
            retVal = identifier("Win32_Processor", "ProcessorId");
            if (retVal == "")
            {
                retVal = identifier("Win32_Processor", "Name");
                if (retVal == "") 
                {
                    retVal = identifier("Win32_Processor", "Manufacturer");
                }
                retVal += identifier("Win32_Processor", "MaxClockSpeed");
            }
        }
        return retVal;
    }

    private static string biosId()
    {
        return identifier("Win32_BIOS", "Manufacturer")
        + identifier("Win32_BIOS", "SMBIOSBIOSVersion")
        + identifier("Win32_BIOS", "IdentificationCode")
        + identifier("Win32_BIOS", "SerialNumber")
        + identifier("Win32_BIOS", "ReleaseDate")
        + identifier("Win32_BIOS", "Version");
    }

    private static string diskId()
    {
        return identifier("Win32_DiskDrive", "Model")
        + identifier("Win32_DiskDrive", "Manufacturer")
        + identifier("Win32_DiskDrive", "Signature")
        + identifier("Win32_DiskDrive", "TotalHeads");
    }

    private static string baseId()
    {
        return identifier("Win32_BaseBoard", "Model")
        + identifier("Win32_BaseBoard", "Manufacturer")
        + identifier("Win32_BaseBoard", "Name")
        + identifier("Win32_BaseBoard", "SerialNumber");
    }

    private static string videoId()
    {
        return identifier("Win32_VideoController", "DriverVersion")
        + identifier("Win32_VideoController", "Name");
    }

    private static string macId()
    {
        return identifier("Win32_NetworkAdapterConfiguration", 
            "MACAddress", "IPEnabled");
    }

GetUniqueID() 是散列各种 ID 的函数。为什么有互联网和没有互联网时生成的 ID 不同?

【问题讨论】:

  • 如何删除大量代码并仅显示理解您的问题真正需要的内容?
  • @UweKeim 你检查代码了吗?大部分代码都在使用中
  • 一点调试应该可以让您自己检测到差异...例如,生成的 id 在连接或断开连接时是否相同?您已经尝试了解自己的是什么?
  • @PeterBons 通过从哈希中删除 mac 解决了这个问题...为什么 mac id 在有/没有互联网连接的情况下会有所不同?

标签: c# windows winapi uniqueidentifier


【解决方案1】:

我认为这是因为当您断开连接时,您的网络接口被禁用,因此无法检索 MAC 地址。

【讨论】:

    【解决方案2】:

    你不能简单地使用设备的 MAC id 而不是这 1000 行复杂的逻辑。它将始终保持不变,或者设备序列号是设备的 Bios 序列号。即使没有网络,也可以使用 Bios 密钥。

    【讨论】:

    • mac id 在有/没有网络的情况下会改变吗?因为从哈希中删除 mac id 解决了我的问题
    • @mrid IMO,你应该真的 learn how to use a debugger.
    • @UweKeim 指出 :)
    【解决方案3】:

    我的团队曾经尝试构建一段类似的代码,以便在不使用持久存储的情况下根据机器设置生成唯一 ID。例如Hash(hostname, username, domain name, mac address, etc...)。在当时似乎是一个好主意,但事实证明它本质上是不可靠的,因为一些在返回这些值时应该保持一致的 API 并不总是如此。

    更简单、更可靠的方法是生成一个 GUID 并将其保存到注册表(或磁盘上的文件,甚至是 Windows 凭据存储)。

        static string GetUniqueID()
        {
            string result;
            string registry_path = "HKEY_CURRENT_USER\\Software\\MyApp";  // substitue your own app name here
            Object obj = Registry.GetValue(registry_path, "UniqueID", null);
            if ((obj == null) || !(obj is string))
            {
                result = Guid.NewGuid().ToString();
                Registry.SetValue(registry_path, "UniqueID", result);
            }
            else
            {
                result = (string)obj;
            }
            return result;
        }
    

    它也比调用 WMI 更快。

    【讨论】:

    • 这样,如果我知道程序将系统 ID 保存在哪里,我就可以在我的系统上使用其他人的许可证。
    • OP 从未说过存储许可证密钥。但是即使密钥可以仅从环境中推断出来,确定的黑客仍然可以找到使用调试器拦截密钥的方法。您保护秘密值的程度应取决于您试图阻止的黑客攻击的决心程度。
    【解决方案4】:

    我认为你选错了教程。

    由于 2 个原因,当您连接/断开连接时 MAC 会发生变化。首先,大多数 PC 有超过 1 个网卡,并且它们在 WMI 中出现的顺序是不确定的。其次,默认情况下,Windows 10 有时会在每次连接 WiFi 网络时randomizes WiFi MAC address

    您使用的其他 ID 也好不到哪里去。

    videoId 不稳定,因为更新驱动时驱动版本会更新,顺便说一句,一些 windows 更新包含新版本的 GPU 驱动

    diskId 不稳定,因为用户插入 USB 闪存驱动器或外部硬盘驱动器。

    cpuId 不可靠,因为它仅包含特定于 CPU 型号的信息,即对于主流 CPU,您将在世界上拥有数百万具有相同 cpuId 的人。

    【讨论】:

      猜你喜欢
      • 2017-12-03
      • 2020-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-21
      • 2020-03-25
      • 2011-06-07
      相关资源
      最近更新 更多