首页 > 编程 > C# > 正文

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

2019-10-29 21:38:04
字体:
来源:转载
供稿:网友

本文使用RSA非对称加密和Base64简单地实现离线注册码的生成与验证功能。感兴趣的朋友跟着小编一起学习吧

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

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

一、 生成公密钥

RSACryptoServiceProvider cryptor = new RSACryptoServiceProvider();

File.WriteAllText("PrivateKey.xml", cryptor.ToXmlString(true));

File.WriteAllText("PublicKey.xml", cryptor.ToXmlString(false));

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

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

二、 生成注册码

 

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

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

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

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

三、 验证注册码

 

 
  1. static bool Verify(string regCode) 
  2. const string PUBLIC_KEY = ""
  3. try 
  4. RSACryptoServiceProvider cryptor = new RSACryptoServiceProvider(); 
  5. cryptor.FromXmlString(PUBLIC_KEY); 
  6. byte[] signedData = Convert.FromBaseString(regCode); 
  7.  
  8. bool today = cryptor.VerifyData( 
  9. Encoding.UTF.GetBytes(String.Format("[{}][{}]", DateTime.Now.ToString("yyyy-MM-dd"))), 
  10. "SHA", signedData); 
  11. bool machineToday = cryptor.VerifyData( 
  12. Encoding.UTF.GetBytes(String.Format("[{}][{}]", MAC, DateTime.Now.ToString("yyyy-MM-dd"))), 
  13. "SHA", signedData); 
  14. bool forever = cryptor.VerifyData( 
  15. Encoding.UTF.GetBytes(String.Format("[{}][{}]", MAC, Environment.MachineName)), 
  16. "SHA", signedData); 
  17. return today || machineToday || forever; 
  18. catch 
  19. return false

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

需要注意:

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

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

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

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表