博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Serializable]的应用--注册码的生成,加密和验证
阅读量:5103 次
发布时间:2019-06-13

本文共 7361 字,大约阅读时间需要 24 分钟。

1.首先定义注册类RegisterEntity

[Serializable]    public class RegisterEntity    {        public string RegisterKey;        public bool IsRegistered;        public List
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
registerOrder = new List
(); 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;        }

输入序列号后,注册,验证序列号是否有效,如果有效,则激活软件

 

转载于:https://www.cnblogs.com/ceee/p/4932585.html

你可能感兴趣的文章
ionic2+ 基础
查看>>
[leetcode]Minimum Path Sum
查看>>
Aizu - 1378 Secret of Chocolate Poles (DP)
查看>>
IO流写出到本地 D盘demoIO.txt 文本中
查看>>
Screening technology proved cost effective deal
查看>>
mysql8.0.13下载与安装图文教程
查看>>
Thrift Expected protocol id ffffff82 but got 0
查看>>
【2.2】创建博客文章模型
查看>>
从零开始系列之vue全家桶(1)安装前期准备nodejs+cnpm+webpack+vue-cli+vue-router
查看>>
Jsp抓取页面内容
查看>>
大三上学期软件工程作业之点餐系统(网页版)的一些心得
查看>>
可选参数的函数还可以这样设计!
查看>>
[你必须知道的.NET]第二十一回:认识全面的null
查看>>
Java语言概述
查看>>
关于BOM知识的整理
查看>>
使用word发布博客
查看>>
面向对象的小demo
查看>>
微服务之初了解(一)
查看>>
GDOI DAY1游记
查看>>
收集WebDriver的执行命令和参数信息
查看>>