# LicenseTools **Repository Path**: zc-tek_0/license-tools ## Basic Information - **Project Name**: LicenseTools - **Description**: 一个自用的软件离线授权的工具,参考了许多大佬的代码。 - **Primary Language**: C# - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 28 - **Created**: 2023-08-28 - **Last Updated**: 2023-08-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 离线授权机制 ![离线授权机制](readme.assets/离线授权机制.png) ## 客户端生成序列号 1. 客户端随机生成AES密钥,利用该密钥对机器的硬件信息HardwareInfo进行加密, 2. 客户端将密钥本身和加密信息拼接成机器序列号SN ``` HardwareInfo = CPU SN + GPU SN + MainBoard SN + BIOS SN + MAC SN = AES Key + Length(AES(HardwareInfo)) + AES(HardwareInfo) ``` ## 服务端生成授权文件 1. 服务端使用RSA私钥对机器序列号SN进行签名,利用SN中携带的AES密钥对授权时间进行加密 2. 服务端将机器序列号SN、签名内容Sign(SN)、AES加密后的授权时间AES(time)拼接成授权信息License,保存到文件中 ``` License = SN + Sign(SN) + AES(time) ``` ## 客户端验证授权文件 1. 客户端读取授权文件的内容,使用RSA公钥对签名内容进行验证 2. 签名验证通过后,客户端生成硬件信息HardwareInfo,和授权文件中截取的硬件信息进行比较 3. 硬件信息确认无误后,使用授权文件携带的AES密钥解密授权时间,判断当前的系统时间是否在授权时间内,并修改最后一次校验的时间为当前时间 # 使用说明 ![image-20230503101339459](readme.assets/image-20230503101339459.png) 解决方案共有三个项目 ## LicenseClient 生成动态链接库,供客户机器使用,用于生成机器序列号和验证授权文件,在上位机软件中引用该库文件即可,包含如下三个API: ```c# //生成机器序列号 string GenSerialNo() //验证授权信息是否有效 bool VerifyLicense(string license, string publicKey) license:授权码 publicKey:公钥,由服务端生成,和上位机安装包一起打包发送给客户 //更新验证时间 bool UpdateVerifyTime(string license,string path) license:授权码 path:保存授权码的文件路径 ``` ### 申请授权 客户申请授权时,在上位机软件中调用以下函数生成机器序列号,可保存到txt文件中发送给我们 ```c# string GenSerialNo() ``` 然后我们使用后面提供的应用程序生成授权文件,发送给客户,放在指定的路径下 ### 验证授权 验证授权文件时,在上位机软件中调用以下函数,先验证授权是否有效,无论是否有效都建议更新授权时间 ```c# bool VerifyLicense(string license, string publicKey) bool UpdateVerifyTime(string license,string path) ``` ## LicenseServer 生成动态链接库,自己使用,用于生成授权文件,不能提供给客户 建议直接使用下面的应用程序,不用浪费时间再去开发 ## LicenseGenerator 生成和验证授权文件的桌面应用程序 可根据机器序列号生成授权文件,验证授权文件有效性,设置授权时间等 # 存在问题 ## 离线时间验证 离线授权的时间验证取决于机器的系统时间,系统时间是可以随意修改,暂时没有很好的解决办法 如果按照参考资料中的设计思路将授权时间作为签名的一部分(签名的内容不能发生变化),则在授权过期后客户端可以通过修改系统时间来通过验证 本系统中将授权时间单独用AES加密,不作为签名内容,同时更新每次验证授权的时间(限制了时间只能递增),使得客户端无法在授权过期后通过单纯更改系统时间来通过验证,但是依然可以保存某个授权有效的时间节点的授权文件,通过 修改授权文件+修改系统时间 的方式通过验证 # 参考资料 设计思路 https://zhuanlan.zhihu.com/p/187585495 硬件信息获取 https://cloud.tencent.com/developer/article/1013187 RSA加解密、签名、验签 https://www.yesdotnet.com/archive/post/1621872135.html AES加解密 https://learn.microsoft.com/zh-cn/dotnet/api/system.security.cryptography.aes?view=net-6.0