推荐+1置顶+1分享、讨论、实现)

通用软件注册功能之建立有效的软件保护机制

众所周知,一些共享软件往往提供给使用者的是一个功能不受限制的限时使用版,在试用期内使用者可以无限制的使用软件的全部功能(只是可能会出现提示使用者注册的窗口),试用期一过部分(或全部)功能失效,要想继续使用只能向作者索取注册码(或注册文件)完成对软件的合法注册,注册后的软件将解除一切使用限制。如果您也开发出一个有价值的作品,是否也希望为自己的软件增加一个这样的功能呢?当前对于.NET反编译的问题不在本文讨论之内,相关文章已经很多!本文我们就一起探讨软件注册功能的实现。

实现软件的注册功能方法很多,最需要考虑的就是不能轻易的让使用者破解,在这里,我就谈谈“.NET快速开发整合框架(RDIFramework.NET)”中平台注册功能的实现方法。在RDIFramework.NET中,注册功能主要方法就是对计算机唯一硬件信息进行RSA数字签名达到软件注册和保护的功能,该方法实现简单,安全性相应较高。

计算机唯一硬件信息(我们知道计算机中的关键部件如CPU,主板等在全球范围内都有一个独一无二的产品序列号,用户通过注册模块获取这些产品序列号(即传统所说的:机器吗)并将它发送给软件开发商要求进行RSA数据签名,软件开发商获得这些机器码后利用手中的私钥对这些信息进行RSA数字签名,生成的签名信息(即注册码)发回给用户,用户将收到的注册码输入注册模块的注册码框,软件即可利用公钥执行签名验证,如果输入的注册码被证明就是经过开发商数字签名的机器码,则完成注册过程。

注册功能项目结构图如下所示:

图1 注册功能项目结构

平台服务端注册码生成主界面如下所示:

图2 注册文件管理器

通过“注册文件管理器”,我们就可以根据用户提供的信息来生成软件的注册文件。

客户端的注册主要就是根据我们提供的注册文件与公钥,来验证注册文件是否为当前客户的有效注册文件,如果有效,注册成功,无效则注册失败!客户端注册功能设计参考如下所示:

图3 平台注册

用户单击“注册”按钮,成功注册提示:

图4注册成功

服务端注册码生成核心代码:

一、     生成公/私钥文件:

1 private void btnGenerateKey_Click(objectsender, EventArgs e)2 {3             if (MessageBox.Show("确定生成生成公/私钥对吗(是/否)?", "询问信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Question)4                 ==System.Windows.Forms.DialogResult.Cancel)5 {6                 return;7 }8   9             RSACryptoServiceProvider crypt = newRSACryptoServiceProvider();10            11             string publicKey = crypt.ToXmlString(true);12             string privateKey   = crypt.ToXmlString(false);13 crypt.Clear();14   15             //生成公钥  16             using (StreamWriter sw = new StreamWriter(KeyPath + "RDIFrameworkkey.key", false, UTF8Encoding.UTF8))17 {18 sw.Write(SecretHelper.AESEncrypt(publicKey));19 sw.Flush();20 }21   22             //生成私钥  23             using (StreamWriter sw = new StreamWriter(KeyPath + "RDIFrameworkPrivateKey.key", false, UTF8Encoding.UTF8))24 {25 sw.Write(SecretHelper.AESEncrypt(privateKey));26 sw.Flush();27 }28             29             MessageBox.Show("成功生成公/私钥对!","提示信息",MessageBoxButtons.OK,MessageBoxIcon.Information);30         }

二、     生成注册文件:

1 private void btnGenerateRegisterFile_Click(objectsender, EventArgs e)2 {3             if (string.IsNullOrEmpty(txtUserEmail.Text.Trim()))4 {5                 MessageBox.Show("用户邮箱不能为空!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);6 txtUserEmail.Focus();7                 return;8 }9             else  10 {11                 if (!RegexValidatorHelper.IsMatch(txtUserEmail.Text.Trim(), Pattern.EMAIL))12 {13                     MessageBox.Show("邮箱格式不正确!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);14 txtUserEmail.SelectAll();15                     return;16 }17 }18   19             if (string.IsNullOrEmpty(txtCPUSerialNo.Text.Trim()))20 {21                 MessageBox.Show("CPU序列号不能为空!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);22                 return;23 }24   25             if (!string.IsNullOrEmpty(txtUseLimited.Text.Trim()))26 {27                 if (!RegexValidatorHelper.IsMatch(txtUseLimited.Text.Trim(), Pattern.INTEGER))28 {29                     MessageBox.Show("使用次数应该为数值型!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);30 txtUseLimited.SelectAll();31                     return;32 }33 }34   35             //读取私钥  36             StreamReader sr = new StreamReader(KeyPath + "RDIFrameworkPrivateKey.key", UTF8Encoding.UTF8);37             string keypair =sr.ReadToEnd();38 sr.Close();39   40             //用私钥参数初始化RSACryptoServiceProvider类的实例crypt。  41             RSACryptoServiceProvider crypt = newRSACryptoServiceProvider();42   43 crypt.FromXmlString(SecretHelper.AESDecrypt(keypair));44   45             UTF8Encoding enc = newUTF8Encoding();46   47             string trialTime = "30";//试用次数(默认:30数,0:表示永久)  48             if (!string.IsNullOrEmpty(txtUseLimited.Text.Trim()))49 {50                 trialTime =txtUseLimited.Text.Trim();51 }52             string regInfo = txtUserEmail.Text.Trim() + ";" + txtMAC.Text.Trim() + ";" + txtCPUSerialNo.Text.Trim() + ";" +trialTime;53   54             byte[] bytes = enc.GetBytes(regInfo);//格式:邮箱地址;MAC;CPU序列号;试用时间55             //对用户信息加密  56             bytes = crypt.Encrypt(bytes, false);57               58             //生成注册数据,对二进制字节进行Base64编码,但采用注册文件的形式的进修也可以不做此转化。  59             string encrytText = System.Convert.ToBase64String(bytes, 0, bytes.Length);60   61             //将注册码写入文件  62             using (StreamWriter sw = new StreamWriter(KeyPath + "RDIFramework_reg_file.lic", false, UTF8Encoding.UTF8))63 {64 sw.Write(encrytText);65 sw.Flush();66 }67   68             MessageBox.Show("注册文件:RDIFramework_reg_file.lic生成成功!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);69         }

三、     验证注册文件:

1 private void btnCheckRegistr_Click(objectsender, EventArgs e)2 {3             //读取注册数据文件  4             StreamReader sr = new StreamReader(KeyPath + "RDIFramework_reg_file.lic", UTF8Encoding.UTF8);5             string encrytText =sr.ReadToEnd();6 sr.Close();7   8   9             //读取公钥  10             StreamReader srPublickey = new StreamReader(KeyPath + "RDIFrameworkkey.key", UTF8Encoding.UTF8);11             string publicKey =srPublickey.ReadToEnd();12 srPublickey.Close();13   14             //用公钥初化始RSACryptoServiceProvider类实例crypt。  15             RSACryptoServiceProvider crypt = newRSACryptoServiceProvider();16 crypt.FromXmlString(SecretHelper.AESDecrypt(publicKey));17             UTF8Encoding enc = newUTF8Encoding();18             byte[] decryptByte;19             try  20 {21                 byte[] newBytes;22                 newBytes = System.Convert.FromBase64CharArray(encrytText.ToCharArray(), 0, encrytText.Length);23                 decryptByte = crypt.Decrypt(newBytes, false);24                 string decrypttext =enc.GetString(decryptByte);25                 //  26                 //TODO:在此处添加验证逻辑27                 //28 MessageBox.Show(decrypttext);29 }30             catch(Exception ex)31 {32 MessageBox.Show(ex.Message);33 }34         }

至此,软件的注册功能就完成了,当然还有其他很多方法,比如:

一、 采用加密狗的方式(最安全的方式)。    二、 在线验证注册信息(用户需能上网),这种方式也比较可靠。    三、 其他方法,欢迎大家讨论。    四、  ......

本文转自yonghu86 51CTO博客,原文链接:http://blog.51cto.com/yonghu/1321315,如需转载请自行联系原作者

推荐+1置顶+1(分享、讨论、实现)通用软件注册功能之建立有效的软件保护机制...相关推荐

  1. 推荐+1置顶+1(分享、讨论、实现) 通用软件注册功能之建立有效的软件保护机制

    推荐+1置顶+1(分享.讨论.实现) 通用软件注册功能之建立有效的软件保护机制 众所周知,一些共享软件往往提供给使用者的是一个功能不受限制的限时使用版,在试用期内使用者可以无限制的使用软件的全部功能( ...

  2. 抖音视频如何置顶?分享抖音视频置顶功能的介绍!

    抖音是现在最火的短视频软件,每当我们查看其他抖音用户的主页时,可以发现它们的界面中有置顶视频,那么到底应该怎么置顶自己的视频呢? 目前来说,获得抖音的[视频置顶]功能主要有两种方式: 第一种:认证蓝V ...

  3. 软件能力[置顶] 程序员如何成为设计师,软件公司如何成为苹果?

    上班之余抽点时间出来写写博文,希望对新接触的朋友有帮助.今天在这里和大家一起学习一下软件能力 /**************************************************** ...

  4. [置顶] 给Fedora修改默认的软件下载源

    (转载请注明:http://www.wypblog.com/archives/124,请不要用于商业目的.) Fedora安装完毕之后最头疼的问题就是软件更新,因为Fedora默认的更新源服务器是在国 ...

  5. [置顶] QUI继续之 -- 添加JS模板引擎功能, 征集LOGO

    <?xml version="1.0" encoding="UTF-8"?> <data> <widget id='QUI.Wid ...

  6. [置顶]Blender 三维绘图及渲染软件 (开源优秀强大跨平台)

    Blender 是什么? Blender 的构想提出于 1993 年 12 月,1994 年 8 月成为可用的产品,以可同时创作 2D 和 3D 作品的集成应用软件的身份诞生.Blender 提供了囊 ...

  7. 微信在朋友圈强行置顶视频号直播分享,引网友疯狂吐槽:又丑又烦!

    前几天,微信iOS版本进行了更新,除了对iPhone 12分辨率进行支持外,还有许多的功能也进入了灰度测试的过程,其中有关于视频号的功能居多. 微信对于视频号的功能是非常重视的,在几次大的更新中,视频 ...

  8. 【原创分享】窗口置顶小工具

    跟大家分享个日常的小工具--窗口置顶工具,如下图,简简单单的功能,可快捷键操作. 平常操作电脑屏幕就那么点大,办公的时候窗口切换来切换去的很麻烦,就像下面这样打开个Excel和计算器,要么来回切换窗口 ...

  9. 朋友圈加粗字体数字_独家:微信更新!公众号改版,朋友圈视频号直播置顶支持一键关闭...

    刚刚,微信安卓端内测更新至7.0.21版本,上线多项新功能,此前被大部分用户吐槽的"朋友圈置顶朋友分享视频号直播"功能也在这次得到了解决. 1."朋友圈置顶朋友分享的直播 ...

最新文章

  1. 4.36域名重定向4.37用户认证4.38Nginx访问日志4.39日志不记录静态文件4.40日志切割...
  2. memset()函数介绍
  3. Scala入门到精通——第十七节 类型参数(一)
  4. 聊聊高并发(三十)解析java.util.concurrent各个组件(十二) 理解CyclicBarrier栅栏
  5. 两表左连接count某一字段_表连接解决多日留存率问题|SQL
  6. 牛客题霸 [三个数的最大乘积]C++题解/答案
  7. 解决:springcloud 启动 config-client 报错:... .integration.config.HandlerMethodArgumentResolversHolder
  8. 如何深入学习python_菜鸟如何学好python
  9. 赛门铁克运维注意事项
  10. BZOJ4737 组合数问题 【Lucas定理 + 数位dp】
  11. Android Studio Xposed模块编写(一)
  12. 深度linux 官网,深度OS
  13. Win11 安卓子系统 (WSA) 安装包教程 - 电脑运行 Android 手机应用 / 安装 APK 方法
  14. 谷歌表格快捷键_所有最好的Google表格键盘快捷键
  15. 计蒜客 青出于蓝胜于蓝
  16. 三层交换机和二层交换机区别是什么
  17. 新起典|《奇妙·夜德天蚂拐节》定终身场景多媒体内容升级项目
  18. 数据中台与数据湖概念认知
  19. 微信集成(帆软报表)
  20. 2018谷歌开发者节深圳站,Testin云测的AI应用案例获广泛关注

热门文章

  1. javascript中数据访问性能优化简析
  2. 算法分析与设计「二」递归算法
  3. 使用VS2010+OpenCV2.4.9简单图像水印代码
  4. Dart 2-Day
  5. 栈的复习(加减乘除表达式求值)
  6. MyBatis日志插件:Mybatis Log Plugin——将控制台输出的mybatis日志转化成可执行的sql语句
  7. scrapy不抓取重复的网页解决办法
  8. C++中new和malloc
  9. Spring MVC对象转换说明
  10. APUE 12.7 取消选项