[Serializable]的应用--注册码的生成,加密和验证
1.首先定义注册类RegisterEntity

[Serializable]
public class RegisterEntity
{
public string RegisterKey;
public bool IsRegistered;
public List<int> RegisterOrder;
public DateTime RegisterDate;
public DateTime ExpireDate;
}

RegisterKey,注册码(序列号)
IsRegistered,是否已注册
RegisterOrder,注册顺序,由于打开注册码生成文件的时候会暴露Guid,这里作了一个简单的加密算法,打乱顺序后存入RegisterKey,而打乱后的顺序会存入这个List,
RegisterDate,注册日期
ExpireDate,过期日期
2.生成序列号

private RegisterEntity GenerateRegisterKey(RegisterEntity registerEntity)
{
StringBuilder fakeKey = new StringBuilder();
string keyPart;
List<int> registerOrder = new List<int>();
int splitCount = 4;
int currentOrder = 0;
for (int i = 0; i < splitCount; i++)
{
keyPart = Guid.NewGuid().ToString().Substring(0, 6).ToUpper();
currentOrder = new Random().Next(1, splitCount + 1);
while (registerOrder.Contains(currentOrder - 1))
{
Thread.Sleep(100);
currentOrder = new Random().Next(1, splitCount + 1);
}
registerOrder.Add(currentOrder - 1);
keyPart += "-";
fakeKey.Append(keyPart);
}
fakeKey.Remove(fakeKey.Length - 1, 1);
message = fakeKey.ToString();
registerEntity.RegisterOrder = registerOrder;
return registerEntity;
}

这里随机生成了4个六位的Guid,用三个“-”连接起来就是序列号的格式了,打乱顺序用了Random方法,这样顺序也就只有电脑知道了,如果想复杂点可以把splitCount设置大一点,甚至可以把24个字母全部打乱,也就比较难破解了
3.加密

private string EncipherRegisterKey(RegisterEntity registerEntity)
{
string[] fakeKeyArgs = message.Split('-');
string[] realKeyArgs = new string[4]; for (int i = 0; i < fakeKeyArgs.Length; i++)
{
realKeyArgs[registerEntity.RegisterOrder[i]] = fakeKeyArgs[i];
} StringBuilder realKey = new StringBuilder();
string keyPart = string.Empty;
for (int i = 0; i < realKeyArgs.Length; i++)
{
keyPart = realKeyArgs[i].ToString() + "-";
realKey.Append(keyPart);
}
realKey.Remove(realKey.Length - 1, 1);
return realKey.ToString();
}

实际上加密应该包括第2步,这里只是把序列号按照随机打乱的顺序重新组合了一下
4.把生成的Key写入文件

public string GenerateRegisterKeyToBinFile(string registerFileName)
{
message = string.Empty;
try
{
registerEntity = new RegisterEntity();
GenerateRegisterKey(registerEntity); // encipher 加密
registerEntity.RegisterKey = EncipherRegisterKey(registerEntity); registerEntity.IsRegistered = false; IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(registerFileName, FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, registerEntity);
stream.Close();
}
catch (Exception ex)
{
message = "Error: " + ex.Message;
return message;
}
return message;
}

在这里,每次生成新Key的时候由于会覆盖旧文件,而验证的时候是读取Key文件进行比对,所以在这里把IsRegistered设成了false
5.解密

private string DecipherRegisterKey(RegisterEntity registerEntity)
{
string[] realKeyArgs = registerEntity.RegisterKey.Split('-');
string[] fakeKeyArgs = new string[4];
if (!Utility.isNullOrEmptyLst(registerEntity.RegisterOrder) && !Utility.isNullOrEmpty(realKeyArgs))
{
for (int i = 0; i < realKeyArgs.Length; i++)
{
fakeKeyArgs[i] = realKeyArgs[registerEntity.RegisterOrder[i]];
}
} StringBuilder decipherKey = new StringBuilder();
string keyPart = string.Empty;
for (int i = 0; i < fakeKeyArgs.Length; i++)
{
keyPart = fakeKeyArgs[i].ToString() + "-";
decipherKey.Append(keyPart);
}
decipherKey.Remove(decipherKey.Length - 1, 1); return decipherKey.ToString();
}

细心的朋友会发现,解密其实和加密差不多,只是fakeKeyArgs和realKeyArgs的顺序换下,是的,验证Key的时候是比较fakeKey而不是真正存储在文件里的realKey
6.验证Key的有效性以及是否过期

public bool CheckRegister(string registerFileName)
{
RegisterEntity registerEntity = new RegisterEntity();
try
{
string dBFilePath = string.Format("{0}\\{1}", Directory.GetCurrentDirectory(), registerFileName);
if (File.Exists(dBFilePath))
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(registerFileName, FileMode.Open,
FileAccess.Read, FileShare.Read);
registerEntity = (RegisterEntity)formatter.Deserialize(stream);
stream.Close();
if (registerEntity.IsRegistered == true && registerEntity.ExpireDate < DateTime.Today)
{
registerEntity.IsRegistered = false; formatter = new BinaryFormatter();
stream = new FileStream(registerFileName, FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, registerEntity);
stream.Close();
}
}
}
catch (Exception ex)
{
return false;
}
return registerEntity.IsRegistered;
}

是指打开软件的时候识别序列号是否已经过期或者是否已经注册
7.注册并验证

public bool RegisterKey(string inputKey, string registerFileName)
{
RegisterEntity registerEntity = new RegisterEntity();
try
{
string dBFilePath = string.Format("{0}\\{1}", Directory.GetCurrentDirectory(), registerFileName);
if (File.Exists(dBFilePath))
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(registerFileName, FileMode.Open,
FileAccess.Read, FileShare.Read);
registerEntity = (RegisterEntity)formatter.Deserialize(stream);
stream.Close(); string fakeKey = DecipherRegisterKey(registerEntity); if (inputKey == fakeKey)
{
registerEntity.IsRegistered = true;
registerEntity.RegisterDate = DateTime.Today;
registerEntity.ExpireDate = registerEntity.RegisterDate.AddDays(30); //Enable Register Key
formatter = new BinaryFormatter();
stream = new FileStream(registerFileName, FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, registerEntity);
stream.Close();
}
}
}
catch (Exception ex)
{
return false;
}
return registerEntity.IsRegistered;
}

输入序列号后,注册,验证序列号是否有效,如果有效,则激活软件
[Serializable]的应用--注册码的生成,加密和验证的更多相关文章
- 使用apache htpasswd生成加密的password文件,并使用.htaccess控制文件夹訪问
htpasswd 是apache的小工具.在apache安装文件夹bin下可找到. Usage: htpasswd [-cmdpsD] passwordfile username htpasswd - ...
- (6) openssl passwd(生成加密的密码)
该伪命令用于生成加密的密码 [root@docker121 ssl]# man -f passwd passwd (1) - update user's authentication tokens p ...
- 第十五个知识点:RSA-OAEP和ECIES的密钥生成,加密和解密
第十五个知识点:RSA-OAEP和ECIES的密钥生成,加密和解密 1.RSA-OAEP RSA-OAEP是RSA加密方案和OAEP填充方案的同时使用.现实世界中它们同时使用.(这里介绍的只是&quo ...
- openssl生成签名与验证签名
继上一篇RSA对传输信息进行加密解密,再写个生成签名和验证签名. 一般,安全考虑,比如接入支付平台时,请求方和接收方要互相验证是否是你,就用签名来看. 签名方式一般两种,对称加密和非对称加密.对称加密 ...
- Yii2处理密码加密及验证
在Yii2中提供了密码加密以及验证的一系列方法,方便我们的使用,它使用的是bcrypt算法.查看源码我们可以发现它使用的是PHP函数password_hash()和crypt()生成. 加密: /** ...
- 利用strut2标签自动生成form前端验证代码
利用strut2标签自动生成form前端验证代码,使用到的技术有1.struts2标签,如<s:form> <s:textfieled>2.struts2读取*Validati ...
- shiro盐值加密并验证
在数据表中存的密码不应该是123456,而应该是123456加密之后的字符串,而且还要求这个加密算法是不可逆的,即由加密后的字符串不能反推回来原来的密码,如果能反推回来那这个加密是没有意义的.著名的加 ...
- 第十六个知识点:描述DSA,Schnorr,RSA-FDH的密钥生成,签名和验证
第十六个知识点:描述DSA,Schnorr,RSA-FDH的密钥生成,签名和验证 这是密码学52件事系列中第16篇,这周我们描述关于DSA,Schnorr和RSA-FDH的密钥生成,签名和验证. 1. ...
- (转)DES、RSA、MD5、SHA、随机生成加密与解密
一.数据加密/编码算法列表 常见用于保证安全的加密或编码算法如下: 1.常用密钥算法 密钥算法用来对敏感数据.摘要.签名等信息进行加密,常用的密钥算法包括: DES(Data Encr ...
随机推荐
- UDP通讯程序设计---6
一.函数化 1.1服务器使用的函数 创建socket----->socket 绑定地址-------->bind 接受数据-------->recvfrom 发送数据-------- ...
- POJ-2378 Tree Cutting
题目大意:一棵n个节点的树,找出所有的点满足:删除它之后,产生的最大(这里节点数最多即为最大)新树中节点数不超n的一半. 题目分析:两次深搜,过程类似求重心. 代码如下: # include<i ...
- 团队项目开发中,常见的版本控制有svn,git
团队项目开发中,常见的版本控制有svn,git
- ExtJS控件样式修改及美化
Extjs项目对富客户端开发提供了强有力的支持,甚至改变了前端的开发方式,使得开发变得更加趋向于“面向组件”.对界面的美化而言,也是根本性的改变.普通的网页美工面对extjs项目根本无法下手,需要脚本 ...
- 论文笔记之:Heterogeneous Image Features Integration via Multi-Modal Semi-Supervised Learning Model
Heterogeneous Image Features Integration via Multi-Modal Semi-Supervised Learning Model ICCV 2013 本文 ...
- Web前端开发笔试&面试_04_20161019MTBS
1.运用CSS3 ,实现div 沿Y 轴上下循环运动的动画. 我写是:-webkit-animation:xz 3s linear 1s infinite //即XZ轴变化,Y轴不变 正确答案是: & ...
- linux服务之audit
http://blog.chinaunix.net/uid-20786165-id-3167391.html http://blog.chinaunix.net/uid-8389195-id-1741 ...
- codevs-1447取出整数的一部分
说实在的,这个题目真不想写了…… 1447 取出整数的一部分 题目描述 Description 假如有一个整数(int):145678,现在我做截取该数一部份的操作,如输入4,返回前4位即1456;如 ...
- mysql四种事务隔离级的说明
·未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据 ·提交读(Read Committed):只能读取到已经提交的数据.Oracle等多数数据库默 ...
- servlet & filter & listener & interceptor
web.xml 的加载顺序是:context- param -> listener -> filter -> servlet * Servlet 对URL生效,用户处理用户的URL请 ...