zoukankan      html  css  js  c++  java
  • C#软件加序列号激活、试用期限

    现在做软件试用限制,那么就讨论下软件的试用限制。总体来说,限制的方法有这么几种:

    1.时间限制。

    2.次数限制。

            以时间限制为例,主要是用户从安装之日起, 限制用户使用天数。n天之后,就无法使用。这种限制主要是安装的时候,将当前日期写入注册表(或者硬盘上某文件)。当然,写入的是加密过的乱码字符。运行软件时,首先读取注册表(或者文件),如找不到注册表(或者文件),则提示软件未注册。当正常读取后进行解密,得到注册日期,与当前日期进行比较,如果  当前日期 减去 注册日期 > n(允许试用天数),那么提示软件试用到期,直接退出软件。否则 提示可试用天数, 继续试用软件。  根据以上思路,那么用户可以很容易破解软件。比如更改系统日期、或者删除注册表,重新安装软件等 。

          针对用户的破解,对软件限制进行修改。如果试用软件必须联网,或者需要服务器端(比如聊天软件等客户端软件),当前时间要从去服务器的时间,防止用户更改客户机系统时间。或者服务器上对客户机进行记录,如记录主板id,安装时间,等等。。。

    以上为客户机可联网的做法,当客户机无法上网,切不存在服务器,或者服务器就在本机时。以上做法将无法使用。

          那么对于单机运行的软件,如果需要数据库,我们可以将注册时间等信息写入数据库。或者,我们可以采用一明一暗的做法,注册表是明,在硬盘的某角落,存放隐藏文件。软件需读取两处,对两处进行比较,一致则通过,不一致就退出程序。当然,安装的时候对该文件不替换。 我想用户是不愿意为了使用你的软件而格式化整个硬盘的。

          其实还有做法,就是每次运行软件,先将当前日期与注册表对比,看是否过期。如未过期,就对注册表进行一次更改,更改为当前日期,那么用户即使更改系统日期,他的试用期限也在逐渐缩小。为了防止用户重装,还是采用一明一暗的做法。

          基本上就这些方法吧..  贴上测试代码:

    加密解密类:

    using System;
    using System.Data;
    using System.Configuration;
    using System.Linq;
    using System.Xml.Linq;
    using System.IO;
    using System.Text;
    using System.Security.Cryptography;

    namespace Add_To_Regedit
    {
        public class Encryption
        {
            public static string EncryPW(string Pass, string Key)
            {
                return DesEncrypt(Pass, Key);
            }

            public static string DisEncryPW(string strPass, string Key)
            {
                return DesDecrypt(strPass, Key);
            }

            /////////////////////////////////////////////////////////////////////   
           
            /// <summary>
            /// DES加密
            /// </summary>
            /// <param name="encryptString"></param>
            /// <returns></returns>
            public static string DesEncrypt(string encryptString, string key)
            {
                byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
                byte[] keyIV = keyBytes;
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, provider.CreateEncryptor(keyBytes, keyIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Convert.ToBase64String(mStream.ToArray());
            }

            /// <summary>
            /// DES解密
            /// </summary>
            /// <param name="decryptString"></param>
            /// <returns></returns>
            public static string DesDecrypt(string decryptString, string key)
            {
                byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
                byte[] keyIV = keyBytes;
                byte[] inputByteArray = Convert.FromBase64String(decryptString);
                DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, provider.CreateDecryptor(keyBytes, keyIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }

            //////////////////////////////////////////////////////
        }
    }

    读写注册表类:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Management;
    using System.Security.Cryptography;
    using Microsoft.Win32;

    namespace Test_Form_Time
    {
        class TimeClass
        {
            public static int InitRegedit()
            {
                /*检查注册表*/
                string SericalNumber = ReadSetting("", "SerialNumber", "-1");    // 读取注册表, 检查是否注册 -1为未注册
                if (SericalNumber == "-1")
                {               
                    return 1;
                }

                /* 比较CPUid */
                string CpuId = GetSoftEndDateAllCpuId(1, SericalNumber);   //从注册表读取CPUid
                string CpuIdThis = GetCpuId();           //获取本机CPUId         
                if (CpuId != CpuIdThis)
                {
                    return 2;
                }

                /* 比较时间 */
                string NowDate = TimeClass.GetNowDate();
                string EndDate = TimeClass.GetSoftEndDateAllCpuId(0, SericalNumber);
                if (Convert.ToInt32(EndDate) - Convert.ToInt32(NowDate) < 0)
                {
                    return 3;
                }

                return 0;
            }


             /*CPUid*/
            public static string GetCpuId()
            {
                ManagementClass mc = new ManagementClass("Win32_Processor");
                ManagementObjectCollection moc = mc.GetInstances();

                string strCpuID = null;
                foreach (ManagementObject mo in moc)
                {
                    strCpuID = mo.Properties["ProcessorId"].Value.ToString();
                    break;
                }
               return strCpuID;
            }

            /*当前时间*/
            public static string GetNowDate()
            {
                string NowDate = DateTime.Now.ToString("yyyyMMdd"); //.Year + DateTime.Now.Month + DateTime.Now.Day).ToString();

           //     DateTime date = Convert.ToDateTime(NowDate, "yyyy/MM/dd");
                return NowDate;
            }

            /* 生成序列号 */
            public static string CreatSerialNumber()
            {
                string SerialNumber = GetCpuId() + "-" + "20110915";
                return SerialNumber; 
            }

            /* 
             * i=1 得到 CUP 的id 
             * i=0 得到上次或者 开始时间 
             */
            public static string GetSoftEndDateAllCpuId(int i, string SerialNumber)
            {
                if (i == 1)
                {
                    string cupId = SerialNumber.Substring(0, SerialNumber.LastIndexOf("-")); // .LastIndexOf("-"));

                    return cupId;
                }
                if (i == 0)
                {
                    string dateTime = SerialNumber.Substring(SerialNumber.LastIndexOf("-") + 1);
                  //  dateTime = dateTime.Insert(4, "/").Insert(7, "/");
                  //  DateTime date = Convert.ToDateTime(dateTime);

                    return dateTime;
                }
                else
                {
                    return string.Empty;
                }         
            }

            /*写入注册表*/
            public static void WriteSetting(string Section, string Key, string Setting)  // name = key  value=setting  Section= path
            {
                string text1 = Section;
                RegistryKey key1 = Registry.CurrentUser.CreateSubKey("Software\MyTest_ChildPlat\ChildPlat"); // .LocalMachine.CreateSubKey("Software\mytest");
                if (key1 == null)
                {
                    return;
                }
                try
                {
                    key1.SetValue(Key, Setting);
                }
                catch (Exception exception1)
                {
                    return;
                }
                finally
                {
                    key1.Close();
                }

            }

            /*读取注册表*/
            public static string ReadSetting(string Section, string Key, string Default)
            {
                if (Default == null)
                {
                    Default = "-1";
                }
                string text2 = Section;
                RegistryKey key1 = Registry.CurrentUser.OpenSubKey("Software\MyTest_ChildPlat\ChildPlat");
                if (key1 != null)
                {
                    object obj1 = key1.GetValue(Key, Default);
                    key1.Close();
                    if (obj1 != null)
                    {
                        if (!(obj1 is string))
                        {
                            return "-1";
                        }
                        string obj2 = obj1.ToString();
                        obj2 = Encryption.DisEncryPW(obj2, "ejiang11");
                        return obj2;
                    }
                    return "-1";
                }
               

                return Default;
            }
        }
    }

    调用方式如下:

     int res = TimeClass.InitRegedit();
                if (res == 0)
                {
                    Application.Run(new Form1());
                }
                else if(res == 1)
                {
                    MessageBox.Show("软件尚未注册,请注册软件!");
                }
                else if (res == 2)
                {
                    MessageBox.Show("注册机器与本机不一致,请联系管理员!");
                }
                else if (res == 3)
                {
                    MessageBox.Show("软件试用已到期!");
                }
                else
                {
                    MessageBox.Show("软件运行出错,请重新启动!");
                }

  • 相关阅读:
    linux shell 获取文件夹全文绝对路径
    Selenium自动化获取WebSocket信息
    Automatically generating nice graphs at end of your Load Test with Apache JMeter and JMeter-Plugins
    卡夫卡与风暴:卡夫卡和风暴的明智比较
    Apache Kafka安全| Kafka的需求和组成部分
    Kafka Schema Registry | 学习Avro Schema
    QT 内部使用函数列表
    QT图标添加
    QT快捷键
    QT软件上架以及自启动
  • 原文地址:https://www.cnblogs.com/turnip/p/11942520.html
Copyright © 2011-2022 走看看