前言

在客户端认证的过程中,我们总要获取客户机的唯一识别信息,曾经以为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 = ; i < bt.Length; i++)
{
byte b = bt[i];
int n, n1, n2;
n = (int)b;
n1 = n & ;
n2 = (n >> ) & ;
if (n2 > )
s += ((char)(n2 - + (int)'A')).ToString();
else
s += n2.ToString();
if (n1 > )
s += ((char)(n1 - + (int)'A')).ToString();
else
s += n1.ToString();
if ((i + ) != bt.Length && (i + ) % == ) 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

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

     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 = ; 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#获取机器唯一识别码的更多相关文章

  1. 转Windows Phone8.1 获取手机唯一识别码

    转:http://www.dotblogs.com.tw/martinlau17/archive/2014/07/21/146020.aspx 因小弟比較懶,上次不小心 清空了所有文章 現在重寫了XD ...

  2. MD5做为文件名。机器唯一码有电脑的CPU信息和MAC地址,这两个信息需要在linux或unix系统下才能获取吧。

    可以采用机器(电脑)唯一码 + 上传IP + 当前时间戳 + GUID ( + 随机数),然后MD5做为文件名.机器唯一码有电脑的CPU信息和MAC地址,这两个信息需要在linux或unix系统下才能 ...

  3. iOS获取设备唯一标识的各种方法?IDFA、IDFV、UDID分别是什么含义?

    一.UDID (Unique Device Identifier) UDID的全称是Unique Device Identifier,顾名思义,它就是苹果IOS设备的唯一识别码,它由40个字符的字母和 ...

  4. iOS获取设备唯一标识的8种方法

    8种iOS获取设备唯一标识的方法,希望对大家有用. UDID UDID(Unique Device Identifier),iOS 设备的唯一识别码,是一个40位十六进制序列(越狱的设备通过某些工具可 ...

  5. Atitit 深入了解UUID含义是通用唯一识别码 (Universally Unique Identifier),

    Atitit 深入了解UUID含义是通用唯一识别码 (Universally Unique Identifier), UUID1 作用1 组成1 全球唯一标识符(GUID)2 UUID 编辑 UUID ...

  6. Android 手机上获取物理唯一标识码[转]

    所有添加有谷歌账户的设备可以返回一个 ANDROID_ID 所有的CDMA设备对于 ANDROID_ID 和 TelephonyManager.getDeviceId() 返回相同的值(只要在设置时添 ...

  7. IOS开发之——OpenUDID的使用获取用户唯一设备

    下载网址:https://github.com/ylechelle/OpenUDID OpenUDID测试结果分析 1)优点: a.没有用到MAC地址.MAC地址跟UDID一样,存在隐私问题.不能保证 ...

  8. ios开发——实用技术篇OC篇&获取设备唯一标识

    获取设备唯一标识 WWDC 2013已经闭幕,IOS7 Beta随即发布,界面之难看无以言表...,简直就是山寨Android. 更让IOS程序猿悲催的是,设备唯一标识的MAC Address在IOS ...

  9. java生成UUID通用唯一识别码 (Universally Unique Identifier)

    转自:http://blog.csdn.net/carefree31441/article/details/3998553 UUID含义是通用唯一识别码 (Universally Unique Ide ...

随机推荐

  1. BZOJ 2038

    基础不牢:补莫队算法: 莫队算法入门题: 2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 26 ...

  2. HDU1435,好开心,稳定婚姻

    费了三天,终于解决了各种BUG,PASS,好开心,这才是ACM真正的快乐,就在AC的那刻, 网上基本没甚程序,开始被各种变量名搞晕,无语!!! 有几个题目没说的东西:认为序号是1-N, 然后先排序,弄 ...

  3. 遭遇Asp.Net长文件名下载的问题和解决办法

    在Asp.Net中写了一个附件上传和下载的程序,附件上传到数据库中,然后将附件的GUID保存起来,我们可以根据GUID来找到数据库中的附件,一般附件下载的代码是: <!--<br /> ...

  4. 疯狂java讲义——多态

    父类 f = new 子类(); 引用变量f,在编译时类型是父类,在运行时类型是子类类型.当这个引用变量调用子类重写父类的那个方法的时候,实际执行的是子类中重写后的那个方法.当运行的时候调用该变量的方 ...

  5. Swift 2.0 到底「新」在哪?

    [编者按]2015年6月,一年一度的苹果 WWDC 大会如期而至,在大会上苹果发布了 Swift 2.0,引入了很多新的特性,以帮助开发者更快.更简单地构建应用.本篇文章作者是 Maxime defa ...

  6. Gvim for php 安装配置

    VIM for PHP Windows 2011-05-14 11:51:51|  分类: Php|举报|字号 订阅     虽然vim本质上只是一个编辑器.但只要配合一些适当的插件,vim也能变成一 ...

  7. C Primer Plus之指针

    c之精髓——指针(pointer)——用来存储地址的变量.一般来讲,指针是一个其数值为地址的变量(或更一般地说是一个数据对象). 一元运算符&可以取得变量的存储地址,一个变量的地址可以被看作是 ...

  8. jmeter 异步子请求测试随笔

    好久没写技术类的博客了,都不知道自己都在忙啥.... 最近陆续遇到了一些异步子请求的测试需求,比如打开某一个页面A,A页面里的js会再调用B,C,D,E等请求,针对这个页面的测试,我最近做了一些思考: ...

  9. ffmpeg转码MPEG2-TS的音视频同步机制分析

    http://blog.chinaunix.net/uid-26000296-id-3483782.html 一.FFmpeg忽略了adaptation_field()数据 FFmpeg忽略了包含PC ...

  10. JavaWeb项目开发案例精粹-第4章博客网站系统-001设计

    1. 2. 3. # MySQL-Front 5.0 (Build 1.0) /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE */; /*!40101 SET SQL_MO ...