C#软件加序列号激活、试用期限

2023-10-27

道高一尺,魔高一丈。

程序员想尽各种办法给软件加密,用户就想尽各种办法对软件破解。

现在做软件试用限制,那么就讨论下软件的试用限制。总体来说,限制的方法有这么几种:

1.时间限制。

2.次数限制。

        以时间限制为例,主要是用户从安装之日起, 限制用户使用天数。n天之后,就无法使用。这种限制主要是安装的时候,将当前日期写入注册表(或者硬盘上某文件)。当然,写入的是加密过的乱码字符。运行软件时,首先读取注册表(或者文件),如找不到注册表(或者文件),则提示软件未注册。当正常读取后进行解密,得到注册日期,与当前日期进行比较,如果  当前日期 减去 注册日期 > n(允许试用天数),那么提示软件试用到期,直接退出软件。否则 提示可试用天数, 继续试用软件。  根据以上思路,那么用户可以很容易破解软件。比如更改系统日期、或者删除注册表,重新安装软件等 。

      针对用户的破解,对软件限制进行修改。如果试用软件必须联网,或者需要服务器端(比如聊天软件等客户端软件),当前时间要从去服务器的时间,防止用户更改客户机系统时间。或者服务器上对客户机进行记录,如记录主板id,安装时间,等等。。。

以上为客户机可联网的做法,当客户机无法上网,切不存在服务器,或者服务器就在本机时。以上做法将无法使用。

      那么对于单机运行的软件,如果需要数据库,我们可以将注册时间等信息写入数据库。或者,我们可以采用一明一暗的做法,注册表是明,在硬盘的某角落,存放隐藏文件。软件需读取两处,对两处进行比较,一致则通过,不一致就退出程序。当然,安装的时候对该文件不替换。 我想用户是不愿意为了使用你的软件而格式化整个硬盘的。

      其实还有做法,就是每次运行软件,先将当前日期与注册表对比,看是否过期。如未过期,就对注册表进行一次更改,更改为当前日期,那么用户即使更改系统日期,他的试用期限也在逐渐缩小。为了防止用户重装,还是采用一明一暗的做法。

      基本上就这些方法吧..  贴上测试代码:

加密解密类:


 using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace Add_To_Regedit
{
    public class Encryption
    {
        public static string EncryPW(string Pass, string Key)
        {
            return DesEncrypt(Pass, Key);
        }

        public static string DisEncryPW(string strPass, string Key)
        {
            return DesDecrypt(strPass, Key);
        }

        /   
       
        /// <summary>
        /// DES加密
        /// </summary>
        /// <param name="encryptString"></param>
        /// <returns></returns>
        public static string DesEncrypt(string encryptString, string key)
        {
            byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
            byte[] keyIV = keyBytes;
            byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            MemoryStream mStream = new MemoryStream();
            CryptoStream cStream = new CryptoStream(mStream, provider.CreateEncryptor(keyBytes, keyIV), CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length);
            cStream.FlushFinalBlock();
            return Convert.ToBase64String(mStream.ToArray());
        }

        /// <summary>
        /// DES解密
        /// </summary>
        /// <param name="decryptString"></param>
        /// <returns></returns>
        public static string DesDecrypt(string decryptString, string key)
        {
            byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
            byte[] keyIV = keyBytes;
            byte[] inputByteArray = Convert.FromBase64String(decryptString);
            DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
            MemoryStream mStream = new MemoryStream();
            CryptoStream cStream = new CryptoStream(mStream, provider.CreateDecryptor(keyBytes, keyIV), CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length);
            cStream.FlushFinalBlock();
            return Encoding.UTF8.GetString(mStream.ToArray());
        }

        //
    }
}

读写注册表类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Security.Cryptography;
using Microsoft.Win32;

namespace Test_Form_Time
{
    class TimeClass
    {
        public static int InitRegedit()
        {
            /*检查注册表*/
            string SericalNumber = ReadSetting("", "SerialNumber", "-1");    // 读取注册表, 检查是否注册 -1为未注册
            if (SericalNumber == "-1")
            {               
                return 1;
            }

            /* 比较CPUid */
            string CpuId = GetSoftEndDateAllCpuId(1, SericalNumber);   //从注册表读取CPUid
            string CpuIdThis = GetCpuId();           //获取本机CPUId         
            if (CpuId != CpuIdThis)
            {
                return 2;
            }

            /* 比较时间 */
            string NowDate = TimeClass.GetNowDate();
            string EndDate = TimeClass.GetSoftEndDateAllCpuId(0, SericalNumber);
            if (Convert.ToInt32(EndDate) - Convert.ToInt32(NowDate) < 0)
            {
                return 3;
            }

            return 0;
        }


         /*CPUid*/
        public static string GetCpuId()
        {
            ManagementClass mc = new ManagementClass("Win32_Processor");
            ManagementObjectCollection moc = mc.GetInstances();

            string strCpuID = null;
            foreach (ManagementObject mo in moc)
            {
                strCpuID = mo.Properties["ProcessorId"].Value.ToString();
                break;
            }
           return strCpuID;
        }

        /*当前时间*/
        public static string GetNowDate()
        {
            string NowDate = DateTime.Now.ToString("yyyyMMdd"); //.Year + DateTime.Now.Month + DateTime.Now.Day).ToString();

       //     DateTime date = Convert.ToDateTime(NowDate, "yyyy/MM/dd");
            return NowDate;
        }

        /* 生成序列号 */
        public static string CreatSerialNumber()
        {
            string SerialNumber = GetCpuId() + "-" + "20110915";
            return SerialNumber; 
        }

        /* 
         * i=1 得到 CUP 的id 
         * i=0 得到上次或者 开始时间 
         */
        public static string GetSoftEndDateAllCpuId(int i, string SerialNumber)
        {
            if (i == 1)
            {
                string cupId = SerialNumber.Substring(0, SerialNumber.LastIndexOf("-")); // .LastIndexOf("-"));

                return cupId;
            }
            if (i == 0)
            {
                string dateTime = SerialNumber.Substring(SerialNumber.LastIndexOf("-") + 1);
              //  dateTime = dateTime.Insert(4, "/").Insert(7, "/");
              //  DateTime date = Convert.ToDateTime(dateTime);

                return dateTime;
            }
            else
            {
                return string.Empty;
            }         
        }

        /*写入注册表*/
        public static void WriteSetting(string Section, string Key, string Setting)  // name = key  value=setting  Section= path
        {
            string text1 = Section;
            RegistryKey key1 = Registry.CurrentUser.CreateSubKey("Software\\MyTest_ChildPlat\\ChildPlat"); // .LocalMachine.CreateSubKey("Software\\mytest");
            if (key1 == null)
            {
                return;
            }
            try
            {
                key1.SetValue(Key, Setting);
            }
            catch (Exception exception1)
            {
                return;
            }
            finally
            {
                key1.Close();
            }

        }

        /*读取注册表*/
        public static string ReadSetting(string Section, string Key, string Default)
        {
            if (Default == null)
            {
                Default = "-1";
            }
            string text2 = Section;
            RegistryKey key1 = Registry.CurrentUser.OpenSubKey("Software\\MyTest_ChildPlat\\ChildPlat");
            if (key1 != null)
            {
                object obj1 = key1.GetValue(Key, Default);
                key1.Close();
                if (obj1 != null)
                {
                    if (!(obj1 is string))
                    {
                        return "-1";
                    }
                    string obj2 = obj1.ToString();
                    obj2 = Encryption.DisEncryPW(obj2, "ejiang11");
                    return obj2;
                }
                return "-1";
            }
           

            return Default;
        }
    }
}

调用方式如下:

int res = TimeClass.InitRegedit();
            if (res == 0)
            {
                Application.Run(new Form1());
            }
            else if(res == 1)
            {
                MessageBox.Show("软件尚未注册,请注册软件!");
            }
            else if (res == 2)
            {
                MessageBox.Show("注册机器与本机不一致,请联系管理员!");
            }
            else if (res == 3)
            {
                MessageBox.Show("软件试用已到期!");
            }
            else
            {
                MessageBox.Show("软件运行出错,请重新启动!");
            }

 


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#软件加序列号激活、试用期限 的相关文章

  • C# 静态类型不能用作参数

    public static void SendEmail String from String To String Subject String HTML String AttachmentPath null String Attachme
  • C# SmtpClient编程中如何设置带有中文的附件文件名?

    我的代码如下 ContentType ct new ContentType ct MediaType MediaTypeNames Application Octet ct Name 这是一个很长的中文文件名希望能用它在附件名中 Doc A
  • 为什么 C 程序使用 Scanf 给出奇怪的输出?

    我目前正在学习 C 编程 并且遇到了这个奇怪的输出 Program will try functionalities of the scanf function include
  • 在 Mono 中反序列化 JSON 数据

    使用 Monodroid 时 是否有一种简单的方法可以将简单的 JSON 字符串反序列化为 NET 对象 System Json 只提供序列化 不提供反序列化 我尝试过的各种第三方库都会导致 Mono Monodroid 出现问题 谢谢 f
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • Android NDK 代码中的 SIGILL

    我在市场上有一个 NDK 应用程序 并获得了有关以下内容的本机崩溃报告 SIGILL信号 我使用 Google Breakpad 生成本机崩溃报告 以下是详细信息 我的应用程序是为armeabi v7a with霓虹灯支持 它在 NVIDI
  • MVC 5 中具有 ASP.NET Identity 的 Autofac 不会验证 OWIN 管道中的安全标记

    我在 MVC 5 中设置了 AutoFac 来与 ASP NET Identity 一起使用 表面上一切似乎都工作正常 即用户可以创建帐户并登录 但后来我发现 当安全标记更改时 用户不会注销 通过在 AspNetUsers 表中进行暴力破解
  • 用于在标头更改时重新编译的简单 C 项目的示例 makefile

    有谁有完整的 makefile 可以执行以下操作 如果 HEADER 文件发生更改 则重建项目 cpp 文件在 makefile 中列出 头文件未在 makefile 中列出 头文件允许与 cpp 文件具有不同的名称 部分cpp文件没有头文
  • if constexpr 中的 not-constexpr 变量 – clang 与 GCC

    struct A constexpr operator bool const return true int main auto f auto v if constexpr v A a f a clang 6 接受该代码 GCC 8 拒绝它
  • Unity手游触摸动作不扎实

    我的代码中有一种 错误 我只是找不到它发生的原因以及如何修复它 我是统一的初学者 甚至是统一的手机游戏的初学者 我使用触摸让玩家从一侧移动到另一侧 但问题是我希望玩家在手指从一侧滑动到另一侧时能够平滑移动 但我的代码还会将玩家移动到您点击的
  • Linux 上的 RTLD_LOCAL 和dynamic_cast

    我们有一个由应用程序中的一些共享库构成的插件 我们需要在应用程序运行时更新它 出于性能原因 我们在卸载旧插件之前加载并开始使用新插件 并且只有当所有线程都使用旧插件完成后 我们才卸载它 由于新插件和旧插件的库具有相同的符号 我们dlopen
  • 测量进程消耗的 CPU 时钟

    我用 C 语言编写了一个程序 它是作为研究结果创建的程序 我想计算程序消耗的确切 CPU 周期 精确的循环次数 知道我怎样才能找到它吗 The valgrind tool cachegrind valgrind tool cachegrin
  • 我们可以通过指针来改变const定义的对象的值吗?

    include
  • 如何从 Boost.PropertyTree 复制子树

    我有一些boost property tree ptree 我需要树来删除一些具有特定标签名称的元素 例如 xml 表示源ptree如下
  • ASP.NET Core 中间件与过滤器

    在阅读了 ASP NET Core 中间件之后 我对何时应该使用过滤器以及何时应该使用中间件感到困惑 因为它们似乎实现了相同的目标 什么时候应该使用中间件而不是过滤器 9频道有一个关于此的视频 ASP NET 怪物 91 中间件与过滤器 h
  • 如何在C#中控制datagridview光标移动

    我希望 datagridview 光标向右移动到下一列 而不是在向单元格输入数据后移动到下一行 我试图通过 dataGridView1 KeyDown 事件捕获键来控制光标 但这并不能阻止光标在将数据输入到单元格后移动到下一行 提前感谢你的
  • C:设置变量范围内所有位的最有效方法

    让我们来int举个例子 int SetBitWithinRange const unsigned from const unsigned to To be implemented SetBitWithinRange应该返回一个int其中所有
  • 如何高效计算连续数的数字积?

    我正在尝试计算数字序列中每个数字的数字乘积 例如 21 22 23 98 99 将会 2 4 6 72 81 为了降低复杂性 我只会考虑 连续的数字 http simple wikipedia org wiki Consecutive in
  • Streamwriter 覆盖 txt 文件中的文本

    有没有什么方法可以重新打开流写入器而不创建新的写入对象 因为此时 当调用 WriteOdd 时 streamwriter 正在覆盖在它之前调用的 WriteEven public void WriteEven StreamWriter wr
  • 如果找不到指定的图像文件,显示默认图像的最佳方式?

    我有一个普通的电子商务应用程序 我将 ITEM IMAGE NAME 存储在数据库中 有时经理会拼错图像名称 为了避免 丢失图像 IE 中的红色 X 每次显示产品列表时 我都会检查服务器中是否有与该产品相关的图像 如果该文件不存在 我会将其

随机推荐

  • git pull出现Abort没有原因提示

    使用git pull更新时 出现文件冲突 将冲突文件解决后 再进行pull操作 出现abort 但是没有提示原因 这是由于直接在子文件夹下进行pull操作 而其他级别的文件夹下出现也出现文件冲突 而git发现了冲突但是由于不在当前目录下没有
  • 教你一招:解决u盘插入计算机时提示格式化,如何恢复u盘中的文件

    1 插入U盘时 计算机提示格式化 看到这里 到底是格不格呢 别怕 随便你了 2 查看U盘属性 发现都为零 怎么办呢 u盘上面有很多重要文件啊 别急 继续往下看 3 解决办法 1 下载DiskGenius硬盘恢复软件 安装后打开 软件官方下载
  • 招聘数据采集+数据清洗与分析+数据可视化

    1 需求 1 1 数据采集 1 网站解析 利用 chrome 查看网页源码 分析招聘网站网页结构 1 检查 招聘网站 在网页中右键点击检查 或者 F12 快捷键 进入 如下图的查看元素页面 示例图 1 2 检查网站 点击 Network 勾
  • oracle 9i下在线重定义表

    9i提供了联机重定义表的方法 可以让你在基本不影响原表的DML情况下修改表结构 实际上 联机重定义表并不是完全的联机重定义 在最后交换表名的时候会短暂地锁定原表和中间表 但这个过程很短暂 相对于传统方法来说 这是一个进步 9i提供了联机重定
  • 三千书源——愿成为整理最全的书源合集

    引言 古有弱水三千 今有三千书源 勿埋我心 三千大世界 三千书之源 随着 三千书源 渐渐变得充足起来 感谢收藏 希望可以多来看望勿埋我心 注意 现在主流是3 0书源 欢迎在评论区投稿不错的书源 软件下载 3 0 推荐使用 酷安 Github
  • MTSC2020

    MTSC2020中国互联网测试开发大会深圳站 于 2020 年 11 月 20 日至 21 日在深圳宝立方国际酒店召开 为中国质量保证行业奉上一场为期 2 天的技术盛宴 500 来自世界各地的测试精英们汇聚一堂探讨交流 来自阿里巴巴淘系技术
  • CTF新手题

    CTF Capture The Flag 是一种网络安全技能竞赛 它涉及到多个领域 如密码学 逆向工程 漏洞利用 Web安全等 每个比赛都会有多个题目 每个题目都有一个旗帜 玩家需要通过解决问题 攻击漏洞或破解密码等手段 获取旗帜并提交给比
  • MySQL最全面的优化技巧

    如果面试官问你 你会从哪些维度进行 MySQL 性能优化 你会怎么回答 所谓的性能优化 一般针对的是MySQL查询的优化 既然是优化查询 我们自然要先知道查询操作要经过哪些环节 然后思考可以在哪些环节进行优化 查询操作需要经历的基本环节 S
  • FBX SDK快速简笔(基本)

    FBX SDK快速简笔 摘至官方文档 因不开源 大部分地方官方文档中存在保密 以个人理解进行了一部分的推导 该文章免费并承诺不涉及如何利益 FBX模型的组织结构 FBX是以scene graph的结构来存储模型的所有信息 也可以认为是一个多
  • Weka内置特征选择算法整理

    属性评估方法 CfsSubsetEval 根据属性子集中每一个特征的预测能力以及它们之间的关联性进行评估 ChiSquaredAttributeEval 根据与分类有关的每一个属性的卡方值进行评估 ClassifierSubsetEval
  • Vue基础精讲 —— 详解Vue实例、Vue实例的属性和方法

    Vue实例 基本配置 在 build文件夹 下新建 webpack config practice js 配置文件 内容参考 const path require path const HTMLPlugin require html web
  • Flex4,textArea控件的htmlText属性

    它现在包含Text布局框架 Text Layout Framework TLF 而TLF可以作为许多 Spark text组件的基础 例如RichText RichEditableText TextArea和 TextInput等组件 以及
  • 突发奇想把云服务器刷成了黑群晖 ...

    大家好 我是鸟哥 一个半路出家的程序员 前两天准备把自己10年前买的戴尔电脑刷成黑群晖改造成一台家庭存储服务器 折腾了几天后结果把电脑刷成了蓝屏 彻底报废了 后来又突发奇想 准备把手头上的服务器刷成黑群晖 本以为是无法成功的事 结果却很顺利
  • Ubuntu安装Docker

    一 安装条件 1 操作系统要求 需要以下 Ubuntu 版本之一的 64 位版本 Ubuntu Kinetic 22 10 Ubuntu Jammy 22 04 LTS Ubuntu Focal 20 04 LTS Ubuntu Bioni
  • Oracle数据库预警信息阈值设置以及预警信息自动邮件发送到管理员邮箱

    当数据库处于不理想状态时 默认情况下会通过EM发出预警 也可以通过邮件发送给管理员 要设置电子邮件通知 可在EM上 1任何 Database Control 页中 单击页眉和页脚区中的 Setup 设置 链接 2 在 Setup 设置 页中
  • 工作遇到的问题:mybatis注解@Param和分页count

    目录 mybatis注解 Param 分页Count mybatis注解 Param 基于mybatis注解写sql 出现了一个对象映射问题 一开始我没用 Param 因为当时只有一个入参所以没写springboot是能识别到的 但是我后来
  • boost1.79编译

    系列文章目录 文章目录 系列文章目录 前言 一 编译 1 使用vs2019 命令行 用管理员身份运行 2 执行命令 2 第二种方法 3 boost编译动态库 参考 前言 boost自带一套编译工具bjam bjam本身是跨平台的 并且也要自
  • uni-app 后台升级 静默升级 uniapp 后台更新 静默更新 在线升级

    uni app开发到一段落了 最后的app更新好好搞一下 完美的收尾 哈哈哈 在uni app的文档中可以看到内置了HTML5 引擎 这样我们就可以通过JS语法直接调用Native Java接口通道 可调用几乎所有的系统原生Java API
  • ZIP 软件包管理

    ZIP 也是计算机文件的压缩的算法 原名 Deflate 真空 发明者为菲利普 卡兹 Phil Katz 他于 1989 年 1 月公布了该格式的资料 ZIP 通常使用后缀名 zip 主流的压缩格式包括 tar rar zip war gz
  • C#软件加序列号激活、试用期限

    道高一尺 魔高一丈 程序员想尽各种办法给软件加密 用户就想尽各种办法对软件破解 现在做软件试用限制 那么就讨论下软件的试用限制 总体来说 限制的方法有这么几种 1 时间限制 2 次数限制 以时间限制为例 主要是用户从安装之日起 限制用户使用