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("軟件運行出錯,請重新啟動!");
            }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM