您的位置:首页 > 其它

根据USB 序列号 生成USB Key

2008-09-18 18:13 232 查看
在软件安装的时候,常常要验证软件的有效性,这时候发行产品的时候会附带一个USB Key,主程序运行的时候检查这个Key的合法性,如果通过验证,那么启动主程序。
下面的代码提供了实现该方法的途径:/// <summary>
    /// USB 操作相关
    /// </summary>
    public class UsbUtility
    {
        const string Key_File_Name = "Usb.key";
        /// <summary>
        /// 获取优盘唯一序列号,可能需要以管理员身份运行程序
        /// </summary>
        /// <returns></returns>
        public static string GetUSBId()
        {
            ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher("Select * From Win32_USBHub");
            string id = "";
            foreach (ManagementObject wmi_USB in wmiSearcher.Get())
            {
                string strPath = wmi_USB.Path.RelativePath;
                string[] strArr = strPath.Split('/"');
                string strTemp = strArr[1];
                //VID_ 是真正的优盘标示
                if (strTemp.StartsWith("USB////VID_"))
                    id += strTemp + ";";

            }
            return id.TrimEnd(';');
        }

        /// <summary>
        /// 获取当前UsbKey,根据当前附加的序列号,生成 "序列号,UsbId"格式的字符串,并返回加密后的结果
        /// 如果没有找到设备,那么返回空字符串
        /// 如果返回值为空,请检查 message 的值。
        /// </summary>
        /// <param name="sourceNumber">要附加的序列号</param>
        /// <param name="message">生成的操作信息</param>
        /// <returns>当前加密后的UsbKey字符串</returns>
        public static string  GetCurrentUsbKey(string sourceNumber,out string message)
        {
            string strUsbId = GetUSBId();
            if (strUsbId != "")
            {
                if (strUsbId.Split(';').Length == 1)
                {
                    CheckCode cc = new CheckCode();
                    message = "OK";
                    string strTemp = sourceNumber+","+strUsbId ;
                    return cc.Encode(strTemp);
                }
                else
                {
                    message = "当前有多个U盘,请拨除其它U盘。";
                    return "";
                }
                
            }
            message = "未找到U盘或者U盘没有物理序列号。";
            return "";
        }

        /// <summary>
        /// 将一个新的UsbKey写到当前U盘上
        /// </summary>
        /// <param name="sourceNumber">U盘所在盘符</param>
        /// <param name="sourceNumber">要附加的序列号</param>
        /// <param name="message">生成的操作信息</param>
        /// <returns></returns>
        public static bool WriteUsbKeyFile(string driveName, string sourceNumber,out string message)
        {
           string strCurrentUsbKey = GetCurrentUsbKey(sourceNumber, out message);
           if (strCurrentUsbKey != "")
           {
               if (driveName.EndsWith("//"))
                   driveName += "//";
               string strCurrKeyFileName = driveName + Key_File_Name;
               try
               {
                   using (StreamWriter writer = File.CreateText(strCurrKeyFileName))
                   {
                       writer.Write(strCurrentUsbKey);
                       writer.Flush();
                   }
                   message = "OK";
                   return true;
               }
               catch (Exception ex)
               {
                   message = ex.Message;
               }
           }
           return false;
        }

        /// <summary>
        /// 读取UsbKey文件的内容,返回内容格式为 "序列号,UsbId"格式的字符串
        /// 如果未能正确读取文件,返回空字符。
        /// </summary>
        /// <param name="driveName">U盘所在盘符</param>
        /// <param name="message">操作的消息</param>
        /// <returns>UsbKey文件的内容</returns>
        public static string  ReadUsbKeyFile(string driveName, out string message)
        {
            if (driveName.EndsWith("//"))
                driveName += "//";
            string strCurrKeyFileName = driveName + Key_File_Name;
            message = "";
            try
            {
                string strResult = "";
                using (StreamReader reader = File.OpenText(strCurrKeyFileName))
                {
                    strResult = reader.ReadToEnd();
                }
                if (strResult != "")
                {
                    message = "OK";
                    CheckCode cc = new CheckCode();
                    return cc.Decode(strResult);
                }
                else
                {
                    message = "未能正确读取文件,文件内容可能为空!";
                }
               
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }
            return "";
        }
    }

    /// <summary>
    /// 检查编码情况
    /// </summary>
    class CheckCode
    {
        const string KEY_64 = "fasfgew";
        const string IV_64 = "JDLJMAMI"; //注意了,是8个字符,64位 

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public string Encode(string data)
        {
            byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(KEY_64);
            byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(IV_64);

            DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
            int i = cryptoProvider.KeySize;
            MemoryStream ms = new MemoryStream();
            CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);

            StreamWriter sw = new StreamWriter(cst);
            sw.Write(data);
            sw.Flush();
            cst.FlushFinalBlock();
            sw.Flush();
            return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);

        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public string Decode(string data)
        {
            byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(KEY_64);
            byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(IV_64);

            byte[] byEnc;
            try
            {
                byEnc = Convert.FromBase64String(data);
            }
            catch
            {
                return null;
            }

            DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
            MemoryStream ms = new MemoryStream(byEnc);
            CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(byKey, byIV), CryptoStreamMode.Read);
            StreamReader sr = new StreamReader(cst);
            return sr.ReadToEnd();
        }

    }
在主窗体,使用下面的代码调用:private void btnMakeUsbKey_Click(object sender, EventArgs e)
        {
            string strMessage = "";

            MakeProductNumbers();
            if (UsbUtility.WriteUsbKeyFile(CurrentUSBDriveName, ProductNumbers, out strMessage))
            {
                MessageBox.Show("Usb Key File 生成成功!");
            }
            else
            {
                MessageBox.Show(strMessage);
            }
        }

        private void btnShowUsbKey_Click(object sender, EventArgs e)
        {
            string strMessage = "";

            string strText = UsbUtility.ReadUsbKeyFile(CurrentUSBDriveName, out strMessage);
            if (strText!="")
            {
                MessageBox.Show(strText,"查看USBKEY");
            }
            else
            {
                MessageBox.Show(strMessage,"Error");
            }
        }

        private string _CurrentUSBDriveName = "";

        /// <summary>
        /// 当前USB 驱动器号
        /// </summary>
        public string CurrentUSBDriveName
        {
            get
            {
                if (_CurrentUSBDriveName == "")
                {
                    string[] strDrivers = Environment.GetLogicalDrives();
                    _CurrentUSBDriveName = strDrivers[strDrivers.Length - 1];
                }
                return _CurrentUSBDriveName;
            }
            set
            {
                _CurrentUSBDriveName = value ;
            }
        }
属性 CurrentUSBDriveName 会返回当前最后一个驱动器号,我们认为它是优盘,但是这不是很保险。为此,我们需要监视系统合适插入了U盘,并取得它的盘符。在主窗体中(一定要在主窗体中,不能再用户控件中),加入下面的代码:public const int WM_DEVICECHANGE = 0x219;
        public const int DBT_DEVICEARRIVAL = 0x8000;
        public const int DBT_CONFIGCHANGECANCELED = 0x0019;
        public const int DBT_CONFIGCHANGED = 0x0018;
        public const int DBT_CUSTOMEVENT = 0x8006;
        public const int DBT_DEVICEQUERYREMOVE = 0x8001;
        public const int DBT_DEVICEQUERYREMOVEFAILED = 0x8002;
        public const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
        public const int DBT_DEVICEREMOVEPENDING = 0x8003;
        public const int DBT_DEVICETYPESPECIFIC = 0x8005;
        public const int DBT_DEVNODES_CHANGED = 0x0007;
        public const int DBT_QUERYCHANGECONFIG = 0x0017;
        public const int DBT_USERDEFINED = 0xFFFF;

        protected override void WndProc(ref Message m)
        {
            try
            {
                if (m.Msg == WM_DEVICECHANGE)
                {
                    switch (m.WParam.ToInt32())
                    {
                        case WM_DEVICECHANGE:
                            break;
                        case DBT_DEVICEARRIVAL://U盘插入
                            DriveInfo[] s = DriveInfo.GetDrives();
                            foreach (DriveInfo drive in s)
                            {
                                if (drive.DriveType == DriveType.Removable)
                                {
                                    mpnUC.CurrentUSBDriveName  = drive.Name.ToString();
                                    //
                                    MessageBox.Show("U盘已插入,盘符为:" + drive.Name.ToString() + "/r/n");

                                    break;
                                }
                            }
                            break;
                        case DBT_CONFIGCHANGECANCELED:
                            break;
                        case DBT_CONFIGCHANGED:
                            break;
                        case DBT_CUSTOMEVENT:
                            break;
                        case DBT_DEVICEQUERYREMOVE:
                            break;
                        case DBT_DEVICEQUERYREMOVEFAILED:
                            break;
                        case DBT_DEVICEREMOVECOMPLETE: //U盘卸载
                            MessageBox.Show("U盘已卸载!");
                            break;
                        case DBT_DEVICEREMOVEPENDING:
                            break;
                        case DBT_DEVICETYPESPECIFIC:
                            break;
                        case DBT_DEVNODES_CHANGED:
                            break;
                        case DBT_QUERYCHANGECONFIG:
                            break;
                        case DBT_USERDEFINED:
                            break;
                        default:
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            base.WndProc(ref m);
        }

mpnUC 是一个用户控件,我们设置了它的 CurrentUSBDriveName  属性。
OK,允许程序,我们就生成了一个USB Key 了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: