相关知识点
1. DES加密
des对称加密,是一种比较传统的加密方式,其加密运算、解密运算使用的是同样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密码(称为对称密码),是一种对称加密算法。
DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。
2. 基本原理
- 1、电脑的CPU id+内存id+当前时间 = 字符串S
- 2、利用DES加密 将字符串S变成密文 存于 “MICKey.dat”文件中
- 3、启动程序时对“MICKey.dat”文件进行校验 若符合 则运行应用程序
3. 代码部分
3.1 获取机器码(创建和验证均需要)
注意:
- 1、生成机器码并不局限于CPU_id+Memory_id,也可以是任意的计算机中的唯一识别码,比如硬盘ID,网卡编号(需要留意 通常电脑会有两个网卡)
- 2、若用户添加一张内存条将会导致该加密程序失效!
public class pass_key
{
//定义检验和生成密钥的方法
public static string CpuID; //1.cpu序列号
public static string DiskID; //3.硬盘id
static void Computer()
{
CpuID = GetCpuID();
DiskID = GetDiskID();
}
//获取cpu ID
public static string GetCpuID()
{
try//捕获异常 并处理
{
string cpuInfo = "";//cpu序列号
ManagementClass mc = new ManagementClass("Win32_Processor");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
}
moc = null;
mc = null;
return cpuInfo;
}
catch
{
return "unknow";
}
finally
{
}
}
public string GetMemoryID()
{
try
{
string cpuInfo = "";//cpu序列号
ManagementClass mc = new ManagementClass("Win32_PhysicalMemory");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
cpuInfo = mo.Properties["SerialNumber"].Value.ToString();
}
moc = null;
mc = null;
return cpuInfo;
}
catch
{
return "unknow";
}
finally
{
}
}
//获取硬盘ID
public static string GetDiskID()
{
try
{
String HDid = "";
ManagementClass mc = new ManagementClass("Win32_DiskDrive");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
HDid = (string)mo.Properties["Model"].Value;
}
moc = null;
mc = null;
return HDid;
}
catch
{
return "unknow";
}
finally
{
}
}
public string CreatMachineCode()//创建机器码
{
string deviceIds = GetCpuID() + GetMemoryID();
return deviceIds;
}
3.2 创建MICKey.dat秘钥验证文件
public bool CreatKey(string deviceIds,string add_time)
{
pass_key pass = new pass_key();
string dir = @"MICKey.dat";
dir = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + dir;//相对位置
string date = DateTime.Now.ToString();//获取当前时间
//add_time是从前端界面获取的授权时长
deviceIds = deviceIds + date + add_time;
string key = "12345678";//8位自定义秘钥 用于加密和解密
deviceIds = EncryptDES(deviceIds, key);//以密文形式将授权码存于秘钥文件中 可增加其安全性
byte[] keyData = Encoding.ASCII.GetBytes(deviceIds);
File.WriteAllBytes(dir, keyData);
return true;
}
3.3 验证秘钥文件的方法
public bool VerifyKey(string deviceIds)
{
string dir = @"MICKey.dat";
dir = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + dir;
byte[] superkeyData = File.ReadAllBytes(dir);
string deviceIds2 = Encoding.ASCII.GetString(superkeyData);
string key = "11112222";//这个key为自定义的8位数 用于DES加密
deviceIds2 = DecryptDES(deviceIds2, key);
string VerifyKeyID = deviceIds2.Substring(0, deviceIds.Length);
//机器码是否吻合
if (VerifyKeyID == deviceIds)
{
int t1 = deviceIds2.Length;
int t2 = deviceIds2.Length - 4;
string AddDays = deviceIds2.Substring(deviceIds2.Length - 3, 3);
string VerifyDate = deviceIds2.Substring(deviceIds.Length, 12);//截取12位时间长度 yyyy-mm-dd-hh-mm
DateTime d1 = DateTime.Parse(VerifyDate);
DateTime d2 = d1.AddDays(Convert.ToInt32(AddDays));
DateTime d3 = DateTime.Now;
//textBox1.Text = VerifyKeyID + AddDays + VerifyDate;
//是否过期
if (d2 > d3)
{
System.Windows.MessageBox.Show("授权期限内");
return true;
}
if (d2 < d3)
{
System.Windows.MessageBox.Show("授权过期");
return false;
}
return true;
}
else
{
return false;
}
}
4. 后期试着写成更加好看的界面 比如这样
这个可以自定义授权开始时间和授权时长
5. 代码编写中的关于时间报错
- 时间格式不符合
- 解决:
修改为:string VerifyDate = deviceIds2.Substring(deviceIds.Length, 19);
可以正常运行
同样的 可以根据自己的需要限定为8
(仅比较年月日信息)
完整代码
- 完整代码可以根据该链接下载: