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]的应用--注册码的生成,加密和验证的更多相关文章

  1. 使用apache htpasswd生成加密的password文件,并使用.htaccess控制文件夹訪问

    htpasswd 是apache的小工具.在apache安装文件夹bin下可找到. Usage: htpasswd [-cmdpsD] passwordfile username htpasswd - ...

  2. (6) openssl passwd(生成加密的密码)

    该伪命令用于生成加密的密码 [root@docker121 ssl]# man -f passwd passwd (1) - update user's authentication tokens p ...

  3. 第十五个知识点:RSA-OAEP和ECIES的密钥生成,加密和解密

    第十五个知识点:RSA-OAEP和ECIES的密钥生成,加密和解密 1.RSA-OAEP RSA-OAEP是RSA加密方案和OAEP填充方案的同时使用.现实世界中它们同时使用.(这里介绍的只是&quo ...

  4. openssl生成签名与验证签名

    继上一篇RSA对传输信息进行加密解密,再写个生成签名和验证签名. 一般,安全考虑,比如接入支付平台时,请求方和接收方要互相验证是否是你,就用签名来看. 签名方式一般两种,对称加密和非对称加密.对称加密 ...

  5. Yii2处理密码加密及验证

    在Yii2中提供了密码加密以及验证的一系列方法,方便我们的使用,它使用的是bcrypt算法.查看源码我们可以发现它使用的是PHP函数password_hash()和crypt()生成. 加密: /** ...

  6. 利用strut2标签自动生成form前端验证代码

    利用strut2标签自动生成form前端验证代码,使用到的技术有1.struts2标签,如<s:form> <s:textfieled>2.struts2读取*Validati ...

  7. shiro盐值加密并验证

    在数据表中存的密码不应该是123456,而应该是123456加密之后的字符串,而且还要求这个加密算法是不可逆的,即由加密后的字符串不能反推回来原来的密码,如果能反推回来那这个加密是没有意义的.著名的加 ...

  8. 第十六个知识点:描述DSA,Schnorr,RSA-FDH的密钥生成,签名和验证

    第十六个知识点:描述DSA,Schnorr,RSA-FDH的密钥生成,签名和验证 这是密码学52件事系列中第16篇,这周我们描述关于DSA,Schnorr和RSA-FDH的密钥生成,签名和验证. 1. ...

  9. (转)DES、RSA、MD5、SHA、随机生成加密与解密

    一.数据加密/编码算法列表   常见用于保证安全的加密或编码算法如下:   1.常用密钥算法   密钥算法用来对敏感数据.摘要.签名等信息进行加密,常用的密钥算法包括:   DES(Data Encr ...

随机推荐

  1. java03实验截图

  2. Codeforces Round #373 (Div. 1)

    Codeforces Round #373 (Div. 1) A. Efim and Strange Grade 题意 给一个长为\(n(n \le 2 \times 10^5)\)的小数,每次可以选 ...

  3. linux下遍历目录(转-在于思考)

    遍历目录的主要思想 由于目录就是一颗树,所以遍历目录就转换为遍历一棵树.谈到树的遍历就再熟悉不过了,有树的前序.层次和后序遍历,我使用的是前序遍历,后序遍历和前序遍历本质上一样,而层次遍历要比前两个麻 ...

  4. 奇怪的电梯(HDU1548) (Dijkstra)或者(BFS)

    问题 E: 奇怪的电梯 时间限制: 1 Sec  内存限制: 64 MB提交: 35  解决: 16[提交][状态][讨论版] 题目描述 有一天桐桐做了一个梦,梦见了一种很奇怪的电梯.大楼的每一层楼都 ...

  5. Android sdk 镜像服务器资源

    大连东软信息学院镜像服务器地址:- http://mirrors.neusoft.edu.cn 端口:80北京化工大学镜像服务器地址:- IPv4: http://ubuntu.buct.edu.cn ...

  6. android loginDemo +WebService用户登录验证

        android loginDemo +WebService用户登录验证 本文是基于android4.0下的loginActivity Demo和android下的Webservice实现的.l ...

  7. unity, Graphics.Blit (null, null, mat,0);

    我使用 Graphics.Blit (null, finalRT, mat); 合成出一张finalRT,然后将finalRT用在editor脚本的OnInspector中使用 Graphics.Dr ...

  8. noip2014普及组 比例简化

    题目描述 在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果.例如,对某一观点表示支持的有1498 人,反对的有 902人,那么赞同与反对的比例可以简单的记为1498:902. 不过,如 ...

  9. 目录操作工具类 CopyDir.java

    package com.util; import java.io.*; /** * 1,建立目的目录. 2,遍历源目录. 3,遍历过程中,创建文件或者文件夹. 原理:其实就是改变了源文件或者目录的目录 ...

  10. Linux下Memcached-1.4.10安装

    memcache是一款流行的缓存产品,它分为两个部分:一个是运行在服务器端的memcached进程,一个是在客户端进行调用获取缓存中数据客户端,例如比较常用的PHP客户端.这里,记录一下安装服务器端的 ...