现在做软件试用限制,那么就讨论下软件的试用限制。总体来说,限制的方法有这么几种:
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("软件运行出错,请重新启动!"); }
|
请发表评论