码迷,mamicode.com
首页 > 其他好文 > 详细

[Serializable]的应用--注册码的生成,加密和验证

时间:2015-11-04 23:08:29      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:

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]的应用--注册码的生成,加密和验证

标签:

原文地址:http://www.cnblogs.com/zhangxiaolei521/p/4937664.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!