zoukankan      html  css  js  c++  java
  • c#获取机器唯一识别码

    前言

    在客户端认证的过程中,我们总要获取客户机的唯一识别信息,曾经以为MAC地址是不会变的,但是现在各种改,特别是使用无线上网卡,MAC地址插一次变一次,所以这样使用MAC就没有什么意义了,怎么办,又开始求助Google,最后找到一个折中的方案

    原理

    通过获取主板、处理器、BIOS、mac、显卡、硬盘等的ID生成唯一识别码

    建议

    1、使用那些不经常更换的模块来生成识别码。

    2、如果经常更换MAC,显卡,硬盘,则不要使用这些ID。

    3、确保使用static变量在整个应用来保存唯一识别码。

    实现

    注意引用System.Management

    using System;
    using System.Management;
    using System.Security.Cryptography;
    using System.Security;
    using System.Collections;
    using System.Text;
    namespace Security
    {
        /// <summary>
        /// Generates a 16 byte Unique Identification code of a computer
        /// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9
        /// </summary>
        public class FingerPrint  
        {
            private static string fingerPrint = string.Empty;
            public static string Value()
            {
                if (string.IsNullOrEmpty(fingerPrint))
                {
                    fingerPrint = GetHash("CPU >> " + cpuId() + "
    BIOS >> " + 
                biosId() + "
    BASE >> " + baseId()
                                //+"
    DISK >> "+ diskId() + "
    VIDEO >> " + 
                videoId() +"
    MAC >> "+ 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;
            }
            #region Original Device ID Getting Code
            //Return a hardware identifier
            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;
            }
            private static string cpuId()
            {
                //Uses first CPU identifier available in order of preference
                //Don't get all identifiers, as it is very time consuming
                string retVal = identifier("Win32_Processor", "UniqueId");
                if (retVal == "") //If no UniqueID, use ProcessorID
                {
                    retVal = identifier("Win32_Processor", "ProcessorId");
                    if (retVal == "") //If no ProcessorId, use Name
                    {
                        retVal = identifier("Win32_Processor", "Name");
                        if (retVal == "") //If no Name, use Manufacturer
                        {
                            retVal = identifier("Win32_Processor", "Manufacturer");
                        }
                        //Add clock speed for extra security
                        retVal += identifier("Win32_Processor", "MaxClockSpeed");
                    }
                }
                return retVal;
            }
            //BIOS Identifier
            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");
            }
            //Main physical hard drive ID
            private static string diskId()
            {
                return identifier("Win32_DiskDrive", "Model")
                + identifier("Win32_DiskDrive", "Manufacturer")
                + identifier("Win32_DiskDrive", "Signature")
                + identifier("Win32_DiskDrive", "TotalHeads");
            }
            //Motherboard ID
            private static string baseId()
            {
                return identifier("Win32_BaseBoard", "Model")
                + identifier("Win32_BaseBoard", "Manufacturer")
                + identifier("Win32_BaseBoard", "Name")
                + identifier("Win32_BaseBoard", "SerialNumber");
            }
            //Primary video controller ID
            private static string videoId()
            {
                return identifier("Win32_VideoController", "DriverVersion")
                + identifier("Win32_VideoController", "Name");
            }
            //First enabled network card ID
            private static string macId()
            {
                return identifier("Win32_NetworkAdapterConfiguration", 
                    "MACAddress", "IPEnabled");
            }
            #endregion
        }
    }

    参考

    http://www.codeproject.com/Articles/28678/Generating-Unique-Key-Finger-Print-for-a-Computer

    补充

    现在遇到一些平板等简陋的机型,竟然获取到的所有设备标识都一样(除了mac),最后只好在本地再生成一个软件自身的标识,然后每次在计算标识的时候附带上,这样不会再重复了吧。

    代码如下:

            private static string localkey()
            {
                string path=Environment.CurrentDirectory + "client.key";
                if (File.Exists(path))
                {
                    StreamReader sr = new StreamReader(path);
                    string key= sr.ReadLine();
                    sr.Close();
                    return key;
                }
                else
                {
                    StreamWriter sw = File.CreateText(path);
                    string key = Guid.NewGuid().ToString();
                    sw.WriteLine(key);
                    sw.Close();
                    return key;
                }
            }

    可以再把该文件设为隐藏等手段,防止用户误操作。

    补充2

    文件容易被误删,还可以写入注册表,除非系统重装,但是需要以管理员权限运行

     1     class RegistryHelper
     2     {
     3         const string _uriDeviecId = "SOFTWARE\YourCompany\YouApp";
     4         public static string GetDeviceId()
     5         {
     6             string ret = string.Empty;
     7             using (var obj = Registry.LocalMachine.OpenSubKey(_uriDeviecId, false))
     8             {
     9                 if (obj != null)
    10                 {
    11                     var value = obj.GetValue("DeviceId");
    12                     if (value != null)
    13                         ret = Convert.ToString(value);
    14                 }
    15             }
    16             return ret;
    17         }
    18 
    19         public static void SetDeviceId()
    20         {
    21             using (MD5 md5Hash = MD5.Create())
    22             {
    23                 byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(DateTime.Now.ToString()));
    24                 StringBuilder sBuilder = new StringBuilder();
    25                 for (int i = 0; i < data.Length; i++)
    26                 {
    27                     sBuilder.Append(data[i].ToString("x2"));
    28                 }
    29 
    30                 string id = sBuilder.ToString();
    31                 using (var tempk = Registry.LocalMachine.CreateSubKey(_uriDeviecId))
    32                 {
    33                     tempk.SetValue("DeviceId", id);
    34                 }
    35             }
    36         }
    37     }
  • 相关阅读:
    RK lvds TF卡修改屏参
    RK3288 recovery ota升级包
    RK G-sensor 测试
    framework 添加新资源
    AlarmManager 闹钟服务
    RK:SIM卡状态显示、隐藏设置搜索栏
    Microsoft 365 解决方案:解析Microsoft Teams的实时事件和Teams Meeting
    Microsoft 365 解决方案:解析Microsoft Teams 实时事件参与角色的职责
    Microsoft 365 解决方案:如何退出其他组织的Microsoft Teams?
    Microsoft Build 2020: Microsoft 365 list,智能信息跟踪应用程序
  • 原文地址:https://www.cnblogs.com/leestar54/p/4375173.html
Copyright © 2011-2022 走看看