欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-11-09 19:03:58
主要思路就是提供者持有密钥,通过rsa加密客户机标识或时间标识,再通过base64加密成不太难看的注册码,然后分发给客户机。 客户机解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也提供了解密的方法,这样就可以验证更多种类的验证码了。