IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    CeeChen发表于 2015-11-04 08:40:00
    love 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]的应用--注册码的生成,加密和验证,转载请注明。



沪ICP备19023445号-2号
友情链接