C# 离线激活码的实现方式

news2024/12/23 18:42:46

一、简介

离线激活码是一种在软件、游戏、应用程序或其他数字产品领域中常用的授权方式,旨在确保产品的合法使用并维护开发者的权益。当用户购买或获得这些产品的使用权后,开发者会提供一个唯一的、一次性的激活码给用户。与在线激活不同,离线激活码允许用户在没有网络连接的情况下完成产品的激活过程,这对于网络环境不稳定或处于无网络环境的用户尤为便利。

效果:

二、实现效果

当前帖子会展现一个激活软件的完整流程,但也只是一个仅供参考的解决方案,我也做的也那么好,虽然如此,但也不是什么小白都能破解的,还是有一定的用处的。

SoftwareVerification

首先,需要新建一个类库,用来处理激活码和验证相关的问题,取名为:SoftwareVerification

新建一个类 ActivationManager,用来生成激活码,验证激活码,和读取硬盘ID,你也可以改为读取CPU,主板序列号等,我测试了下,读取CPU,主板序列号有点慢,所以就没用了。

因为源码中包含了密匙等信息,不能直接拿了就用,需要拿代码混淆工具对当前DLL进行混淆,可以参考我的帖子:

C# dll代码混淆加密_c# 混淆-CSDN博客

在需要激活的软件中,使用这个混淆加密的DLL进行接口调用,并限制部分接口的访问权限,这样才可以确保软件不那么容易被破解。

using System;
using System.IO;
using System.Management;
using System.Security.Cryptography;
using System.Text;

namespace SoftwareVerification
{
    public class ActivationManager
    {
        private static string DllPath = AppDomain.CurrentDomain.BaseDirectory;
        private static string SecretKey = "johusaqj!lkjuh442~34vf?%sfdsfj";

        /// <summary>
        /// 是否激活成功
        /// </summary>
        public static bool IsActivationSuccess { get; set; }

        /// <summary>
        /// 生成激活码
        /// </summary>
        /// <param name="machineCode">机器码</param>
        /// <returns></returns>
        public static string GenerateActivationCode(string machineCode)
        {
            using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(SecretKey)))
            {
                byte[] hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(machineCode));
                return Convert.ToBase64String(hashBytes);
            }
        }

        /// <summary>
        /// 读取本地激活码
        /// </summary>
        /// <returns></returns>
        public static void ReadActivationCode()
        {
            try
            {
                string path = $"{DllPath}activation.key";
                if (!File.Exists(path))
                {
                    ShowActivationForm();
                    return;
                }

                string content = File.ReadAllText(path);
                if (string.IsNullOrEmpty(content))
                {
                    ShowActivationForm();
                    return;
                }

                string decryptAct = AesEncryptionHelper.Decrypt(content);
                string activation = GenerateActivationCode(GetDiskSerialNumber());
                if (activation.Contains(decryptAct))
                {
                    IsActivationSuccess = true;
                    return;
                }
                ShowActivationForm();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 显示激活界面
        /// </summary>
        private static void ShowActivationForm()
        {
            var activationForm = new ActivationForm();
            activationForm.ShowDialog();
        }

        /// <summary>
        /// 保存激活码
        /// </summary>
        /// <param name="code">激活码</param>
        private static void SaveActivationCode(string code)
        {
            if (string.IsNullOrEmpty(code)) return;

            string path = $"{DllPath}activation.key";
            string act = AesEncryptionHelper.Encrypt(code);
            File.WriteAllText(path, act);
        }

        /// <summary>
        /// 验证激活码
        /// </summary>
        /// <param name="inputActivationCode">激活码</param>
        /// <returns></returns>
        internal static bool ValidateActivationCode(string inputActivationCode)
        {
            if (string.IsNullOrEmpty(inputActivationCode))
                return false;

            string activation = GenerateActivationCode(GetDiskSerialNumber());
            if (activation.Contains(inputActivationCode))
            {
                SaveActivationCode(activation);
                IsActivationSuccess = true;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 获取硬盘序列号
        /// </summary>
        /// <returns></returns>
        internal static string GetDiskSerialNumber()
        {
            try
            {
                var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
                foreach (ManagementObject disk in searcher.Get())
                {
                    var serialNum = disk["SerialNumber"];
                    if (serialNum != null)
                        return serialNum.ToString().Trim();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
            return null;
        }
    }
}

新建一个类 AesEncryptionHelper,用来对字符串加密和解密用的

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace SoftwareVerification
{
    public class AesEncryptionHelper
    {
        // 固定的密钥和 IV,请勿在实际生产环境中使用
        private static readonly byte[] Key = Encoding.UTF8.GetBytes("12345678901234567890123456789012"); // 32 字节的密钥
        private static readonly byte[] IV = Encoding.UTF8.GetBytes("1234567890123456"); // 16 字节的 IV

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText"></param>
        /// <returns></returns>
        public static string Encrypt(string plainText)
        {
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;

                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                    return Convert.ToBase64String(msEncrypt.ToArray());
                }
            }
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="cipherText"></param>
        /// <returns></returns>
        public static string Decrypt(string cipherText)
        {
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;

                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

                using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText)))
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                {
                    return srDecrypt.ReadToEnd();
                }
            }
        }
    }
}

添加一个类 LogShow,用来显示提示信息的

using System;
using System.Windows.Forms;

public class LogShow
{
    public Label Label_Log = null;
    private Timer Timers = null;
    private int TimeOut = 3;

    private void Init()
    {
        Timers = new Timer();
        Timers.Interval = (int)TimeSpan.FromSeconds(TimeOut).TotalMilliseconds;
        Timers.Tick += Timers_Tick;
    }

    private void Timers_Tick(object sender, EventArgs e)
    {
        if (Label_Log == null) return;

        Label_Log.Text = string.Empty;
        Timers.Enabled = false;
    }

    public void Show(string message)
    {
        if (Label_Log == null) return;

        Label_Log.Invoke(new Action(() =>
        {
            Label_Log.Text = message;
            if (Timers.Enabled)
                Timers.Enabled = false;
            Timers.Enabled = true;
        }));
    }

    public void Show(string message, params object[] objs)
    {
        if (Label_Log == null) return;

        Label_Log.Invoke(new Action(() =>
        {
            string content = string.Empty;
            if (objs != null && objs.Length > 0)
                content = string.Format(message, objs);
            else
                content = message;

            Label_Log.Text = content;
            if (Timers.Enabled)
                Timers.Enabled = false;
            Timers.Enabled = true;
        }));
    }

    public LogShow() => Init();
}

接下来添加一个 Form 界面,取名:ActivationForm

代码:

using System;
using System.Threading;
using System.Windows.Forms;

namespace SoftwareVerification
{
    public partial class ActivationForm : Form
    {
        public ActivationForm()
        {
            InitializeComponent();
        }

        //提示工具
        private LogShow LogShows = new LogShow();
        //机器码
        private string MachineCode = string.Empty;
        //激活失败次数
        private int ActivationErrorCount;

        private void ActivationForm_Load(object sender, EventArgs e)
        {
            LogShows.Label_Log = Label_Log;

            //显示机器码
            MachineCode = ActivationManager.GetDiskSerialNumber();
            TextBox_MachineCode.Text = AesEncryptionHelper.Encrypt(MachineCode);
        }

        private void ActivationForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!ActivationManager.IsActivationSuccess)
                Application.Exit();
        }

        //激活
        private void Button_Activation_Click(object sender, EventArgs e)
        {
            string act = TextBox_Activation.Text;
            if (string.IsNullOrEmpty(act))
            {
                LogShows.Show("请输入激活码");
                return;
            }
            if (ActivationErrorCount >= 3)
            {
                LogShows.Show("激活失败次数过多");
                return;
            }

            bool result = ActivationManager.ValidateActivationCode(act);
            if (result)
            {
                LogShows.Show("激活成功");
                Thread.Sleep(500);
                this.Close();
            }

            ActivationErrorCount++;
            LogShows.Show("激活码失败,次数:{0}", ActivationErrorCount);
        }

        //复制
        private void Button_Copy_Click(object sender, EventArgs e)
        {
            string content = TextBox_MachineCode.Text;
            if (!string.IsNullOrEmpty(content))
            {
                Clipboard.SetText(content);
                LogShows.Show("复制成功");
            }
        }

        //粘贴
        private void Button_Paste_Click(object sender, EventArgs e)
        {
            TextBox_Activation.Text = (string)Clipboard.GetDataObject().GetData(DataFormats.Text);
        }
    }
}

ActivationCodeGenerate

第二个项目是激活码生成工具,根据机器码来生成激活码,这个软件主要是掌握在软件所有人这边的,你需要给谁激活码,让它发一下机器码,你就可以生成对于的激活码了。

界面如下:

这个界面和上面的 SoftwareVerification 项目中的界面类似,首先需要添加 SoftwareVerification 类库项目的引用,代码如下:

using SoftwareVerification;
using System;
using System.Windows.Forms;

namespace ActivationCodeGenerate
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //提示工具
        private LogShow LogShows = new LogShow();

        private void Form1_Load(object sender, EventArgs e)
        {
            LogShows.Label_Log = Label_Log;
        }

        //粘贴
        private void Button_Paste_Click(object sender, EventArgs e)
        {
            TextBox_MachineCode.Text = (string)Clipboard.GetDataObject().GetData(DataFormats.Text);
        }

        //生成
        private void Button_Generate_Click(object sender, EventArgs e)
        {
            string machineCode = TextBox_MachineCode.Text;
            if (string.IsNullOrEmpty(machineCode))
            {
                LogShows.Show("请输入机器码");
                return;
            }

            machineCode = AesEncryptionHelper.Decrypt(machineCode);
            string activation = ActivationManager.GenerateActivationCode(machineCode);
            TextBox_Activation.Text = activation;
        }

        //复制
        private void Button_Copy_Click(object sender, EventArgs e)
        {
            string content = TextBox_Activation.Text;
            if (!string.IsNullOrEmpty(content))
            {
                Clipboard.SetText(content);
                LogShows.Show("复制成功");
            }
        }
    }
}

测试

新建一个 Winform 项目 Test,用来当做需要激活码的软件,随便加了点文字,要添加 SoftwareVerification 类库项目的引用

代码如下:

using SoftwareVerification;
using System;
using System.Windows.Forms;

namespace Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ActivationManager.ReadActivationCode();
        }
    }
}

项目整体结构如下:

项目源码:

https://download.csdn.net/download/qq_38693757/89767636

运行后效果如下:

结束

如果这个帖子对你有所帮助,欢迎 关注 + 点赞 + 留言

end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2145107.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java工具安装教程

提示:先安装软件打开后关闭&#xff0c;在执行魔法操作 解压后会多个文件夹&#xff0c;从文件夹打开 要魔法哪款软件就打开对应的魔法脚本 比如&#xff1a;idea就运行idea魔法 点击打开 显示下面弹窗则成功&#xff0c;点击确定即可 打开IDEA查看&#xff1a;

51单片机-直流电机(PWM:脉冲宽度调制)实验-会呼吸的灯直流电机调速

作者&#xff1a;Whappy&#xff08;菜的扣脚&#xff09; 脉冲宽度调制&#xff08;Pulse Width Modulation&#xff0c;PWM&#xff09;是一种通过调节信号的占空比来控制功率输出的技术。它主要通过改变脉冲信号的高电平持续时间相对于低电平的时间来调节功率传递给负载的量…

上市公司-客户ESG数据集(dta+xlsx+参考文献)(2009-2023年)

参考《经济问题》中李普玲&#xff08;2024&#xff09;的做法&#xff0c;将供应商与主要客户数据对应起来&#xff0c;并对上市公司及关联上市公司的ESG数据进行匹配&#xff0c;形成“供应商——客户ESG”的数据集&#xff0c;保留客户的销售占比 一、数据介绍 数据名称&am…

标准管理系统Vue项目

系列文章目录 第一章 基础知识、数据类型学习 第二章 万年历项目 第三章 代码逻辑训练习题 第四章 方法、数组学习 第五章 图书管理系统项目 第六章 面向对象编程&#xff1a;封装、继承、多态学习 第七章 封装继承多态习题 第八章 常用类、包装类、异常处理机制学习 第九章 集…

Springboot与minio:

一、介绍 Minio是一个简单易用的云存储服务&#xff0c;它让你可以轻松地把文件上传到互联网上&#xff0c;这样无论你在哪里&#xff0c;只要有网络&#xff0c;就能访问或分享这些文件。如果你想要从这个仓库里取出一张图片或一段视频&#xff0c;让网站的访客能看到或者下载…

硬件体系架构的学习

硬件体系架构的学习 RISC全称Reduced Instruction Set Compute&#xff0c;精简指令集计算机&#xff1b; CISC全称Complex Instruction Set Computers&#xff0c;复杂指令集计算机。 SOC片上系统概念 System on Chip&#xff0c;简称Soc&#xff0c;也即片上系统。从狭义…

Spark-ShuffleWriter-UnsafeShuffleWriter-钨丝内存分配

一、上下文 《Spark-ShuffleWriter-UnsafeShuffleWriter》中提到在进行Page内存分配时&#xff0c;调用了一行代码 MemoryBlock page memoryManager.tungstenMemoryAllocator().allocate(acquired); 这里就会走MemoryManager的钨丝内存分配&#xff0c;下面我们来详细看下 …

python运行时错误:找不到fbgemm.dll

python运行时错误&#xff1a;找不到fbgemm.dll 报错&#xff1a; OSError: [WinError 126] 找不到指定的模块。 Error loading "D:\program\py\312\Lib\site-packages\torch\lib\fbgemm.dll" or one of its dependencies. 原因是Windows下缺失&#xff1a;libomp140…

Mastering openFrameworks_第十一章_网络

网络 网络为多个设备之间的数据交换提供了一种方式。它是一个主要组成部分&#xff0c;允许远程控制移动和平板设备应用程序中的一些参数&#xff0c;也用于使交互式项目在多台计算机上同步工作。在本章中&#xff0c;您将学习如何在openFrameworks项目中实现和使用OSC和TCP协…

BrainSegFounder:迈向用于神经影像分割的3D基础模型|文献速递--Transformer架构在医学影像分析中的应用

Title 题目 BrainSegFounder: Towards 3D foundation models for neuroimagesegmentation BrainSegFounder&#xff1a;迈向用于神经影像分割的3D基础模型 01 文献速递介绍 人工智能&#xff08;AI&#xff09;与神经影像分析的融合&#xff0c;特别是多模态磁共振成像&am…

系统安装CH384串口卡驱动

1. 解压驱动文件CH38XDRV.tar&#xff0c;并进入驱动目录 cd CH38XDRV/DRV_28S/LINUX/driver$ 2. 编译 sudo make edgeedge-PC:~/CH38XDRV/DRV_28S/LINUX/driver$ sudo make 请输入密码: 验证成功 make -C /lib/modules/4.19.0-arm64-desktop/build M/home/edge/CH38XDRV/DRV…

2024年【四川省安全员B证】新版试题及四川省安全员B证考试试卷

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 四川省安全员B证新版试题参考答案及四川省安全员B证考试试题解析是安全生产模拟考试一点通题库老师及四川省安全员B证操作证已考过的学员汇总&#xff0c;相对有效帮助四川省安全员B证考试试卷学员顺利通过考试。 1、…

数据库事务的详解

1、 介绍 什么是事务? 事务是一个原子操作。是一个最小执行单元。可以由一个或多个SQL语句组成&#xff0c;在同一个事务当中&#xff0c;所有的SQL语句都成功执行时&#xff0c;整个事务成功&#xff0c;有一个SQL语句执行失败&#xff0c;整个事务都执行失败。(一组操作同时…

计算机人工智能前沿进展-大语言模型方向-2024-09-14

计算机人工智能前沿进展-大语言模型方向-2024-09-14 1. Multimodal learning using large language models to improve transient identification of nuclear power plants B Qi, J Sun, Z Sui, X Xiao, J Liang - Progress in Nuclear Energy, 2024 使用大型语言模型进行多…

Html在线编辑器

Html在线编辑器提供富文本编辑器,在线文章编辑器,富文本编辑器,Html在线编辑器使用&#xff0c;具有高级功能的Html在线编辑器可全屏编辑,Web版Html在线编辑器在线使用,文章,网站编辑,微信公众号可以在线使用编辑器功能等。

select系统调用(实现I/O复用)

API 在一段指定时间内&#xff0c;监听用户感兴趣的文件描述符上的可读、可写、异常事件。 int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);文件描述符集合fd_set 是一个用于管理文件描述符集合的结构体。select调用…

flutter集成百度地图定位 ‘BMKLocationManager.h‘ file not found报错

一、写在前面 好久不见~最近接手了一个flutter的项目&#xff0c;需求是接入百度地图的定位插件。但是按照官网的文档来做&#xff0c;安卓没有问题&#xff0c;但是ios就惨了&#xff0c;各种编译报错。 flutter_bmflocation: ^3.6.0 集成报错 ‘BMKLocationManager.h’ fil…

Renesas R7FA8D1BH (Cortex®-M85)内部RTC的应用

目录 概述 1 软硬件 1.1 软硬件环境信息 1.2 开发板信息 1.3 调试器信息 2 FSP配置RTC 2.1 配置参数 2.2 RTC模块介绍 3 RTC相关函数 3.1 R_RTC_Open() 3.2 R_RTC_Close() 3.3 R_RTC_ClockSourceSet() 3.4 R_RTC_CalendarTimeSet() 3.5 R_RTC_CalendarTimeGet()…

HC-SR04超声波传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理介绍 三、程序设计 main.c文件 ultrasonic.h文件 ultrasonic.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 HC-SR04超声波传感器是通过发送和接收超声波&#xff0c;利用时间差和声音传播速度…

Python编码系列—Python团队开发工作流:高效协作的艺术

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…