基于C#实现简单离线注册码生成与验证

 更新时间:2015年09月28日 15:01:58   投稿:mrr  
本文使用RSA非对称加密和Base64简单地实现离线注册码的生成与验证功能。感兴趣的朋友跟着小编一起学习吧

主要思路就是提供者持有密钥,通过RSA加密客户机标识或时间标识,再通过Base64加密成不太难看的注册码,然后分发给客户机。

客户机解Base64后,通过持有的公钥来验证注册码是否与本机标识或时间标识相符。

一、 生成公密钥

RSACryptoServiceProvider cryptor = new RSACryptoServiceProvider();
File.WriteAllText("PrivateKey.xml", cryptor.ToXmlString(true));
File.WriteAllText("PublicKey.xml", cryptor.ToXmlString(false));

为了方便长期保存这里就直接存入文件了。

为了避免客户机公钥丢失,我比较倾向于将公钥直接编译到验证程序中,但是这样也就意味着如果更换了密钥,老的验证程序就验不了新生成的注册码了。

二、 生成注册码

 static string CreateRegCode(string mac, DateTime date)
 {
   RSACryptoServiceProvider cryptor = new RSACryptoServiceProvider();
   cryptor.FromXmlString(File.ReadAllText("PrivateKey.xml"));
   string signature = String.Format("[{}][{}]", mac, date.ToString("yyyy-MM-dd"));
   byte[] regCodeBytes = cryptor.SignData(
     Encoding.UTF.GetBytes(signature),
     "SHA");
   return Convert.ToBaseString(regCodeBytes);
 }

这个方法是通过加密MAC和日期的组合来生成注册码,需要注意几点:

1.参数中的MAC是客户机的地址2.第四行的文件是上一步生成的密钥文件

3.由于只考虑验证,所以客户机还必须知道参数中的date

三、 验证注册码

static bool Verify(string regCode)
 {
   const string PUBLIC_KEY = "";
   try
   {
     RSACryptoServiceProvider cryptor = new RSACryptoServiceProvider();
     cryptor.FromXmlString(PUBLIC_KEY);
     byte[] signedData = Convert.FromBaseString(regCode);
 
     bool today = cryptor.VerifyData(
       Encoding.UTF.GetBytes(String.Format("[{}][{}]", DateTime.Now.ToString("yyyy-MM-dd"))),
       "SHA", signedData);
     bool machineToday = cryptor.VerifyData(
       Encoding.UTF.GetBytes(String.Format("[{}][{}]", MAC, DateTime.Now.ToString("yyyy-MM-dd"))),
       "SHA", signedData);
     bool forever = cryptor.VerifyData(
       Encoding.UTF.GetBytes(String.Format("[{}][{}]", MAC, Environment.MachineName)),
       "SHA", signedData);
     return today || machineToday || forever;
   }
   catch
   {
     return false;
   }
 }

这个方法验证了三种类型的注册码:当天可用、本机当天可用和永久可用。

需要注意:

1.第三行的公钥就是第一步的PublicKey.xml中的内容

2.十四和十七行的MAC是客户机的物理地址,至于怎么获取不是本文的重点,请各位看官自行百度

3.考虑到客户机填写的注册码有可能不是合法的Base64文本,需要捕获解析时异常

其实RSACryptoServiceProvider也提供了解密的方法,这样就可以验证更多种类的验证码了。

相关文章

  • C# FileSystemWatcher 在监控文件夹和文件时的使用方法

    C# FileSystemWatcher 在监控文件夹和文件时的使用方法

    这篇文章主要介绍了C# FileSystemWatcher 在监控文件夹和文件时的使用方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以参考下
    2020-06-06
  • C#运算符大全_各种运算符号的概述及作用

    C#运算符大全_各种运算符号的概述及作用

    以下是对C#中各种运算符号的说明及作用进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10
  • 用 FieldMask 提高 C# gRpc 的服务性能

    用 FieldMask 提高 C# gRpc 的服务性能

    这篇文章主要介绍了用 FieldMask 提高 C# gRpc 的服务性能,FieldMask 是一个 protobuf 消息,包含一个名为 paths 的字段,用于指定用于指定读取操作返回或更新操作修改的字,下文详细内容,需要的朋友可以参考一下
    2022-03-03
  • C#实现密码验证与输错密码账户锁定

    C#实现密码验证与输错密码账户锁定

    这篇文章介绍了C#实现密码验证与输错密码账户锁定的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • C#实现SMTP邮件发送程序实例

    C#实现SMTP邮件发送程序实例

    这篇文章主要介绍了C#实现SMTP邮件发送程序实例,是一个非常常见的实用技巧,需要的朋友可以参考下
    2014-10-10
  • 秒表计时器以及STOPWATCH(实例讲解)

    秒表计时器以及STOPWATCH(实例讲解)

    下面小编就为大家分享一篇秒表计时器以及STOPWATCH(实例讲解),具有很好的参考价值,希望对大家有所帮助
    2017-11-11
  • C#实现将浮点数表示的货币数量以汉字大写形式输出的方法

    C#实现将浮点数表示的货币数量以汉字大写形式输出的方法

    这篇文章主要介绍了C#实现将浮点数表示的货币数量以汉字大写形式输出的方法,涉及C#针对浮点数的遍历与字符替换操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08
  • C#实现定义一套中间SQL可以跨库执行的SQL语句(案例详解)

    C#实现定义一套中间SQL可以跨库执行的SQL语句(案例详解)

    这篇文章主要介绍了C#实现定义一套中间SQL可以跨库执行的SQL语句,主要包括hisql查询样例、group by查询、链式查询及hisql语句和链式查询混用的sql语句,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • C# WebClient类用法实例

    C# WebClient类用法实例

    这篇文章主要介绍了C# WebClient类用法实例,本文讲解使用WebClient下载文件、OpenWriter打开一个流使用指定的方法将数据写入到uri以及上传文件示例,需要的朋友可以参考下
    2015-07-07
  • C#中如何自定义配置上周和本周起始日来查询业务数据(思路详解)

    C#中如何自定义配置上周和本周起始日来查询业务数据(思路详解)

    在C#中并没有封装的方法根据我们需要来直接获取上一周某天到某天、本周某天到某天,所以需要我们自己封装方法来实现(我们也可以按照这个思路使用其他语言来实现),感兴趣的朋友跟随小编一起看看吧
    2023-09-09

最新评论