Unity开发授权系统

这篇具有很好参考价值的文章主要介绍了Unity开发授权系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Unity开发授权系统

引子

因为有些客户尾款到账不及时,因此研究了一套授权系统,当授权到期后,系统就提示软件授权已到期,不能继续使用云云,这样方便尾款的收回。文章来源地址https://www.toymoban.com/news/detail-815616.html

大体需求就是
  • 时间相关性,可以自由设置授权到期日期,到达时间后提示过期。
  • 机器相关性,有时候是按照机器来授权的,需要识别不同的机器,分别给客户授权。

思路和需要的技术点

  • 提取机器特征码,可以参考的思路是:CPU序列号、硬盘序列号、主板序列号、网卡MAC地址等。其中,获取MAC地址最简单,但是也最不稳定,客户网络环境如果比较复杂,比如多张网卡,比如拔插网线可能就会导致网卡状态变化,读取时就会有问题。其余的,相对好一点,推荐几个序列号都读取一下,然后拼接使用。但也不是百分百稳定,毕竟各种厂商设备型号繁杂。问题的关键在于如何获取这些序列号,网络上搜寻的解决方案,全都是使用System.Management,然而,这个其实并不能直接在unity中使用。即便是将Unity InstallPath/Editor/Data/MonoBleedingEdge/lib/mono/2.0-api/System.Management.dll文件引入Unity工程,也会报“未实现”的错。所以最终,我的解决方案是写了一个额外的控制台程序,在这个控制台程序中读取硬件信息,然后输出,在Unity中调用这个控制台程序,在后台去获取硬件信息。这就又引发了一系列其他的问题,比如:假设客户知道了原理,如果他伪造一个读取硬件信息的程序,当我unity去调用时,他就可以返回给我假的硬件特征码,比如无论什么机器都返回一个固定的值,这样他就可以只用一台机器的授权,好几台机器共用了。所以,我Unity在调用之前,必须判断好这个读取硬件特征码的软件,是我的软件,而不是他伪造的。还有一个问题,在unity中,调用的时候,必须是后台调用,不能出现任何界面。
    那么两个问题的解决方法,就是:
    1. 在调用外部进程之前,首先创建一个内存映射文件(MemoryMappedFile,它虽然叫做File,但其实它只需要在内存中,实际并不需要磁盘IO),这个内存映射文件,是可以跨进程共享数据的。读硬件特征码的程序,读到硬件信息后,加密后写到这个内容映射文件中,而不是在控制台输出,这样,这个读取硬件特征的软件,客户就很难替换,因为:①客户不知道内存映射文件对象的名称;②客户不知道加密方式,或者说即便知道加密方式,不知道加密的key,无法向内存映射文件中写如正确数值。这样就避免了客户自行替换读硬件信息的程序。
      提取特征码的具体算法,网络上很多,这里不再赘述。
    2. 在unity中静静的运行一个后台进程,其实很容易,这里以获取控制台输出为例:
// 读取机器码的协程
private static IEnumerator ReadMachineCode()
{
    // 启动读取硬件特征码的进程
	string exePath = Path.Combine(Application.streamingAssetsPath, "MachineCode/GetMachineCode.exe");
	if (!File.Exists(exePath))
	{
	    OnMachineCodeReaded?.Invoke(null);
	    yield break;
	}
	
	Process process = new Process();
	process.StartInfo.FileName = exePath;
	process.StartInfo.Arguments = "Your Some Arguments"; // 据实际情况写
	process.StartInfo.UseShellExecute = false;
	process.StartInfo.CreateNoWindow = true;
	process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
	process.StartInfo.WorkingDirectory = Path.Combine(Application.streamingAssetsPath, "MachineCode");
	process.StartInfo.RedirectStandardOutput = true;
	process.Start();
	
	// 等待进程结束
	while (!process.HasExited)
	    yield return null;
	
	// 获取进程运行结果,以控制台为例,而不是内存文件映射,生产环境应读取内存文件映射中的结果
	string result = process.StandardOutput.ReadToEnd();
	OnMachineCodeReaded?.Invoke(result);
}
  • 构建授权数据,本质上是构架一个数据体,用于描述授权文件的信息。然后转换为Json字符串,方便加密和存储。
[Serializable]
internal class MachineLicense
{
    public string code;  // 目标机器码
    public string desc;  // 说明
    public int year;     // 授权到期年
    public int month;    // 授权到期月
    public int day;      // 授权到期日
}
[Serializable]
internal class LicenseData
{
    public string projectName;  // 项目名称
    public string description;	// 说明
    public string check;        // 校验字符串
    public List<MachineLicense> data;  // 授权数据
}
  • AES加密原理,采用AES加密。这也是很成熟的加密算法,下面提供一些与加解密相关的封装好的方法:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public static class AESCryptography
{
	// AES加密
    public static byte[] Encrypt(byte[] rgbKey, byte[] rgbIV, string sourceText)
    {
        using MemoryStream memoryStream = new MemoryStream();
        using (Aes aes = Aes.Create())
        using (ICryptoTransform transform = aes.CreateEncryptor(rgbKey, rgbIV))
        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
        using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
        {
            streamWriter.Write(sourceText);
            streamWriter.Flush();
        }
        return memoryStream.ToArray();
    }

	// AES解密
    public static string Decrypt(byte[] rgbKey, byte[] rgbIV, byte[] cipherBuffer)
    {
        using MemoryStream stream = new MemoryStream(cipherBuffer);
        using Aes aes = Aes.Create();
        using ICryptoTransform transform = aes.CreateDecryptor(rgbKey, rgbIV);
        using CryptoStream cryptoStream = new CryptoStream(stream, transform, CryptoStreamMode.Read);
        using StreamReader streamReader = new StreamReader(cryptoStream);
        return streamReader.ReadToEnd();
    }

	// 字符串MD5加密
    public static byte[] Md5Encrypt(string tex)
    {
        var md5 = MD5.Create();
        return md5.ComputeHash(Encoding.UTF8.GetBytes(tex));
    }

	// 将byte[]数据输出为HEX字符串
    public static string ByteArrayToString(byte [] data)
    {
        StringBuilder sb = new StringBuilder();
        int index = 0;
        foreach( var d in data )
        {
            if (index > 0 && index % 4 == 0)
                sb.Append('-');
            sb.Append(d.ToString("X2"));
            ++index;
        }
        return sb.ToString();
    }

	// 将HEX字符串转换为byte[16]
    public static bool HexStringToByte16(string hex, out byte[] data)
    {
        data = new byte[16];
        int index = 0;
        bool half = true;
        foreach (var ch in hex)
        {
            byte d;
            switch (ch)
            {
                case >= '0' and <= '9':
                    d = (byte)(ch - '0');
                    break;
                case >= 'A' and <= 'F':
                    d = (byte)(10 + (ch - 'A'));
                    break;
                case >= 'a' and <= 'f':
                    d = (byte)(10 + (ch - 'a'));
                    break;
                case ' ':
                case '-':
                case ':':
                    continue;
                default:
                    return false;
            }
            if (half)
                data[index] = (byte) (d << 4);
            else
            {
                data[index] = (byte) ( data[index] | d );
                ++index;
                if (index > 15)
                    break;
            }
            half = !half;
        }
        return true;
    }
}
  • 制作授权文件,Unity端判定授权无效,或授权到期后,系统会停止工作,并将机器码显示到屏幕上,提示授权到期信息等。我方技术人员获取到机器码后,按照上述算法制作授权文件,经过AES加密,生成Base64字符串,保存到授权文件中,交付客户。
  • 授权验证,客户将授权文件存放到指定路径后,Unity端验证过程:首先读取授权文件,并进行解密,转换为解密后的json字符串,再转换为LicneseData数据,如果校验码等信息全部通过后,再判定当前设备机器码是否在授权文件中,并且授权日期是否到期。完成授权验证。
foreach (var date in from target in licenseData.data where string.CompareOrdinal(target.code, MachineCode) == 0 select new DateTime(target.year, target.month, target.day).AddDays(1))
{
    OnLicenseChecked?.Invoke(DateTime.Now < date);
    yield break;
}
OnLicenseChecked?.Invoke(false);

到了这里,关于Unity开发授权系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Node.js实战】一文带你开发博客项目之安全(sql注入、xss攻击、md5加密算法)

    个人简介 👀 个人主页: 前端杂货铺 🙋‍♂️ 学习方向: 主攻前端方向,也会涉及到服务端 📃 个人状态: 在校大学生一枚,已拿多个前端 offer(秋招) 🚀 未来打算: 为中国的工业软件事业效力n年 🥇 推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2Vue3项目实战 🥝

    2024年02月03日
    浏览(52)
  • Unity开发授权系统

    引子 因为有些客户尾款到账不及时,因此研究了一套授权系统,当授权到期后,系统就提示软件授权已到期,不能继续使用云云,这样方便尾款的收回。 大体需求就是 时间相关性,可以自由设置授权到期日期,到达时间后提示过期。 机器相关性,有时候是按照机器来授权的

    2024年01月22日
    浏览(23)
  • MD5密码加密

    密码加密        使用工具类的MD5功能方法,加密密码        注册环节:               1. 获取用户输入密码 123456               2. 调用MD5加密密码,保存新的加密密码到数据库        登录环节:               1. 获取用户输入密码 123456        

    2024年02月16日
    浏览(43)
  • 浅谈Md5+Salt加密

    一 为什么需要加密? 比如当前有个用户进行注册,他输入的账号密码是“ltl”和\\\"123456\\\",那么我们肯定要将账号密码保存到数据库中。在没有接触过“加密”这个概念时,我们肯定是将账号密码以明文的方式保存到user表中。那么明文存放密码会有哪些问题呢? 如果有人能看

    2024年02月04日
    浏览(50)
  • 前端(js)md5加密

    1、引入md5源文件,代码如下,直接复制。 2、在页面引入md5文件。 3、使用md5加密。

    2024年02月11日
    浏览(65)
  • java中MD5加密

    MD5加密是一种常见的加密方式,我们经常用在保存用户密码和关键信息上。那么它到底有什么,又什么好处呢,会被这么广泛的运用在应用开发中。 MD5加密全程是Message-Digest Algoorithm 5(信息-摘要算法),它对信息进行摘要采集,再通过一定的位运算,最终获取加密后的MD5字

    2024年02月05日
    浏览(40)
  • MD5加密--Python实现

    MD5消息摘要算法(MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。 MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit 字节,通常用一个32位的16进制字符串表示。 MD5加密

    2024年02月11日
    浏览(55)
  • postman md5加密传输

    //获取当前时间 let timestamp = (new Date()).getTime().toString();  //取前十位 timestamp = timestamp.substr(0,10); pm.globals.set(\\\"timestamp\\\", timestamp); //md5加密字符串 key = postman.getGlobalVariable(\\\"YuOu.Momtime.Sign\\\"); var strmd5 = CryptoJS.MD5(key+timestamp).toString(); pm.globals.set(\\\"signature\\\", strmd5);

    2024年02月13日
    浏览(43)
  • C# 实现MD5加密

    日常程序开发中,涉及到敏感数据内容,通常会采取加密处理以保证数据安全,本篇文章讲述了在C#中使用MD5方法加密数据 MD5的全称是message-digest algorithm 5,MD5算法属于hash算法的一类,对消息进行运算,产生一个128位的消息摘要(32位数字字母),并且加密不可逆,相同数据

    2024年02月08日
    浏览(48)
  • 微信小程序加密 MD5

    注意: hexMd5: 是 md5.js抛出的             utilMd5  是当前页面JS引入的

    2024年02月12日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包