当前位置 : 主页 > 网络编程 > c#编程 >

c# 获取机器唯一识别码的示例

来源:互联网 收集:自由互联 发布时间:2021-05-09
前言 在客户端认证的过程中,我们总要获取客户机的唯一识别信息,曾经以为MAC地址是不会变的,但是现在各种改,特别是使用无线上网卡,MAC地址插一次变一次,所以这样使用MAC就没

前言

在客户端认证的过程中,我们总要获取客户机的唯一识别信息,曾经以为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() + "\nBIOS >> " + 
  biosId() + "\nBASE >> " + baseId()
    //+"\nDISK >> "+ diskId() + "\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;
 }
 #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
 }
}

补充

现在遇到一些平板等简陋的机型,竟然获取到的所有设备标识都一样(除了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

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

class RegistryHelper
 {
 const string _uriDeviecId = "SOFTWARE\\YourCompany\\YouApp";
 public static string GetDeviceId()
 {
  string ret = string.Empty;
  using (var obj = Registry.LocalMachine.OpenSubKey(_uriDeviecId, false))
  {
  if (obj != null)
  {
   var value = obj.GetValue("DeviceId");
   if (value != null)
   ret = Convert.ToString(value);
  }
  }
  return ret;
 }

 public static void SetDeviceId()
 {
  using (MD5 md5Hash = MD5.Create())
  {
  byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(DateTime.Now.ToString()));
  StringBuilder sBuilder = new StringBuilder();
  for (int i = 0; i < data.Length; i++)
  {
   sBuilder.Append(data[i].ToString("x2"));
  }

  string id = sBuilder.ToString();
  using (var tempk = Registry.LocalMachine.CreateSubKey(_uriDeviecId))
  {
   tempk.SetValue("DeviceId", id);
  }
  }
 }
 }

以上就是c# 获取机器唯一识别码的示例的详细内容,更多关于c# 获取机器识别码的资料请关注自由互联其它相关文章!

网友评论