[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 发送数据-------- ...
- 某种数列问题 (jx.cpp/c/pas) 1000MS 256MB
众所周知,chenzeyu97有无数的妹子(阿掉!>_<),而且他还有很多恶趣味的问题,继上次纠结于一排妹子的排法以后,今天他有非(chi)常(bao)认(cheng)真(zhe)去研究一 ...
- svn 安装 、使用(2)
写在前面的话: p.s.有必要读一读,不然可能会浪费你的时间. 该篇是接着上一篇的,上一篇是看了很多人写的文章,汇总的一些可能的情况,最后还是没有成功.此篇是在一个同学的帮助下成功的,也是在自己做好的 ...
- PHP字符串
<?php $string1 = <<<EVILXR 我有一只小毛驴,我从来也不骑. 有一天我心血来潮,骑着去赶集. 我手里拿着小皮鞭,我心里正得意. 不知怎么哗啦啦啦啦,我摔 ...
- c笔记
关于数组的操作: 初始化: 完全初始化: Int a[5] = {1,3,4,5,6}; 不完全初始化: 未被初始化的元素自动为零 Int a[5] = {1, 3, 4}; 不初始化, 所有元 ...
- javascript往textarea追加内容
<html> <body> <textarea id="content"></textarea> <script> va ...
- IIS_PUT
[*] Put file success http://58.16.95.114:80/1470546504.01.txt [*] Put file success http://58.17.121. ...
- ABBYY FineReader 12 能够识别哪些文档语言
ABBYY FineReader可以识别单语言文本和多语言文本(如使用两种及以上语言).对于多语言文本,需要选择多种识别语言. 要为文本指定一种 OCR 语言,请从主工具栏或任务窗口的文档语言下拉列表 ...
- Deferred和Promise之间有什么区别呢?
一个promise就是一个由异步函数返回的对象. deferred对象就是jQuery的回调函数解决方案. 总结 jQuery 的ajax 就是返回一个promise 对象,里面含有done(), f ...
- mysql的text的类型注意
不要以为text就只有一种类型! Text也分为四种类型:TINYTEXT.TEXT.MEDIUMTEXT和LONGTEXT 其中 TINYTEXT 256 bytes TEXT 65,535 byt ...