ZLicense 1.1.7

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package ZLicense --version 1.1.7
                    
NuGet\Install-Package ZLicense -Version 1.1.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ZLicense" Version="1.1.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ZLicense" Version="1.1.7" />
                    
Directory.Packages.props
<PackageReference Include="ZLicense" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ZLicense --version 1.1.7
                    
#r "nuget: ZLicense, 1.1.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ZLicense@1.1.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ZLicense&version=1.1.7
                    
Install as a Cake Addin
#tool nuget:?package=ZLicense&version=1.1.7
                    
Install as a Cake Tool

ZLicense

通用许可证验证 SDK — 闭源商业软件 · 需授权文件 · Native 安全层 · Obfuscar 混淆

概述

ZLicense 是一套面向 .NET 应用程序的许可证验证 SDK,采用 ECDSA P-256 数字签名 + AES-256-CBC 加密 + 机器指纹绑定 三位一体的授权体系,关键验证逻辑下沉至 C++ Native DLL 执行,配合反调试、防篡改、Authenticode 签名验证等多层安全机制,为闭源商业软件提供可靠的授权保护。

授权说明:本 SDK 为闭源商业软件,使用前需获取授权文件 zlicense.auth.dll,放置于项目根目录或 licenses/ 子目录下。编译时 SDK 会自动验证授权文件的合法性。

特性

特性 说明
ECDSA P-256 签名 基于 SHA-256 + ECDSA P-256 的许可证签名体系,Native 优先 + 托管降级
AES-256-CBC 加密 许可证文件 AES 加密,密钥通过 PBKDF2 从机器指纹派生(10000 次迭代)
机器指纹绑定 采集 CPU / BIOS / 主板 / 磁盘序列号,加权评分容错匹配
Native 安全层 44 个导出函数,关键逻辑下沉 C++ DLL,序号导出避免符号泄露
反调试保护 IsDebuggerPresent + CheckRemoteDebuggerPresent + IAT/EAT Hooking 检测
防篡改检测 时间回滚检测 + 许可证文件哈希校验 + DLL 自校验哈希
Authenticode 验证 可执行文件数字签名校验
试用期管理 基于 DPAPI + 注册表双重加密存储的试用天数追踪
SDK 授权守卫 编译时验证授权 DLL,运行时 ECDSA 签名校验
Obfuscar 混淆 Release 构建自动混淆,公共 API 保留,内部实现重命名为 Unicode 不可读字符
多目标框架 同时支持 net8.0netstandard2.0(.NET Framework 4.6.2+)
依赖注入 通过 AddLicensingSdk() 一键注册所有服务,Native 优先 + 托管回退

安装

dotnet add package ZLicense

安装后需将授权文件 zlicense.auth.dll 放置于项目根目录或 licenses/ 子目录下。

快速开始

1. 注册服务

using ZLicense.SDK;

// 基础注册(默认 1 小时周期性验证)
services.AddLicensingSdk(publicKey, storagePath);

// 自定义周期性验证间隔
services.AddLicensingSdk(publicKey, storagePath, TimeSpan.FromMinutes(30));

// 完整配置(自定义注册表路径和存储目录名)
services.AddLicensingSdk(
    publicKey,                // 91 字节 SPKI 格式 ECDSA P-256 公钥
    storagePath,              // 许可证文件存储目录
    periodicCheckInterval,    // 周期性验证间隔
    registryKeyPath,          // Windows 注册表键路径(篡改检测 + 试用期备份)
    storageDirName            // 本地应用数据目录下的存储子目录名
);

2. 验证许可证

using ZLicense.Core.Contracts;
using ZLicense.Core.Models;

public class MyService
{
    private readonly ILicenseManager _licenseManager;

    public MyService(ILicenseManager licenseManager)
    {
        _licenseManager = licenseManager;
    }

    public async Task DoWorkAsync()
    {
        var result = await _licenseManager.ValidateAsync();

        if (result.IsValid)
        {
            var license = result.License!;
            Console.WriteLine($"许可证有效: {license.ProductName} - {license.CustomerName}");
            Console.WriteLine($"到期时间: {license.ExpireAt:yyyy-MM-dd}");
            Console.WriteLine($"剩余天数: {license.DaysRemaining}");
        }
        else
        {
            Console.WriteLine($"许可证无效: {result.ErrorCode.GetDescription()}");
        }
    }
}

3. 导入许可证

// 从服务端获取的许可证字节数据
await _licenseManager.ImportLicenseAsync(licenseData);

4. 导出许可证请求

using ZLicense.Core.Enums;

// 导出首次激活请求
var requestData = await _licenseManager.ExportRequestAsync(RequestType.InitialActivation);
// 将 requestData 发送至授权服务端

5. 试用期管理

var trialInfo = await _licenseManager.GetTrialInfoAsync();
Console.WriteLine($"试用期: {(trialInfo.IsTrial ? "是" : "否")}");
Console.WriteLine($"剩余天数: {trialInfo.DaysRemaining}");

var isExpired = await _licenseManager.IsTrialExpiredAsync();

6. 验证指定文件

var result = await _licenseManager.ValidateLicenseFileAsync(@"C:\path\to\license.lic");

颁发端用法

生成许可证

using ZLicense.Cryptography;
using ZLicense.Core.Models;
using ZLicense.SDK.Codec;

// 创建加密服务
var signer = CryptographyServices.CreateSigner(privateKeyBytes);
var serializer = CryptographyServices.CreateSerializer();
var fingerprintProvider = new MachineFingerprintProvider();
var codec = new LicenseCodec(serializer, fingerprintProvider);

// 构建许可证
var license = new License
{
    LicenseID = Guid.NewGuid().ToString(),
    CustomerID = "CUST-001",
    CustomerName = "示例客户",
    ProductCode = "PROD-001",
    ProductName = "示例产品",
    Edition = "Professional",
    MachineFingerprint = fingerprintProvider.Generate(),
    IssuedAt = DateTimeOffset.UtcNow,
    ExpireAt = DateTimeOffset.UtcNow.AddYears(1),
    Type = LicenseType.Subscription,
    IsUniversal = false,
    Features = new List<string> { "ModuleA", "ModuleB" }
};

// 签名
var signedLicense = signer.Sign(license);

// 写入加密文件
codec.WriteLicense(signedLicense, "license.lic", encrypt: true);

验证许可证文件

var verifier = CryptographyServices.CreateSignatureVerifier(publicKeyBytes);
var result = verifier.Verify(license, signature);

API 参考

核心接口

接口 说明
ILicenseManager 许可证管理器,验证、导入导出、试用期管理的核心入口
ILicenseCodec 许可证编解码器,文件读写与字节序列化/反序列化
ILicenseValidator 许可证验证器,签名校验 + 机器码匹配 + 有效期检查
ILicenseSerializer 许可证序列化器,License 对象与 JSON 字节数组双向转换
ILicenseSigner 许可证签名器,ECDSA 签名生成
ISignatureVerifier 签名验证器,Native 优先 + 托管降级验证策略
IMachineFingerprintProvider 机器指纹提供者,设备唯一标识生成与相似度计算
ISecureStorage 安全存储,DPAPI 加密的键值对持久化
ITrialManager 试用期管理器,试用天数追踪与过期判断
ITamperDetector 防篡改检测器,时间回滚 + 文件哈希校验

核心模型

License
属性 类型 说明
LicenseID string 许可证唯一标识符
CustomerID string 客户唯一标识符
CustomerName string 客户名称
ProductCode string 产品编码
ProductName string 产品名称
Edition string 版本标识
MachineFingerprint string 绑定的设备机器指纹
IssuedAt DateTimeOffset 签发时间(UTC)
ExpireAt DateTimeOffset 到期时间(UTC)
Signature string? 数字签名(init-only,防反射篡改)
Type LicenseType 许可证类型
IsUniversal bool 是否为万能钥匙(不绑定设备,包含所有功能)
Features List<string> 授权功能列表
DaysRemaining int 距离到期剩余天数(计算属性)
LicenseValidationResult
属性 类型 说明
IsValid bool 验证是否通过
ErrorCode LicenseErrorCode 错误码
Message string 错误描述
License License? 关联的许可证对象
TrialInfo
属性 类型 说明
IsTrial bool 是否处于试用期
DaysRemaining int 剩余天数
StartedAt DateTimeOffset 试用期开始时间(UTC)
ExpireAt DateTimeOffset? 试用期到期时间(UTC)
LicenseRequest
属性 类型 说明
MachineFingerprint string 设备机器指纹
DeviceModel string 设备型号
ProductCode string 产品编码
RequestType RequestType 请求类型
GeneratedAt DateTimeOffset 请求生成时间(UTC)

枚举

LicenseType
说明
Subscription (0) 订阅制,有过期时间
Perpetual (1) 永久授权,不过期
Trial (2) 试用授权,受试用天数限制
RequestType
说明
InitialActivation (0) 首次激活
Renewal (1) 续期
FeatureUpgrade (2) 功能升级
MachineRebind (3) 设备换绑

异常层次

LicenseException                          许可证基础异常
├── SignatureVerificationException        签名验证失败
├── MachineMismatchException              机器码不匹配
├── LicenseExpiredException               许可证已过期
├── TamperDetectedException               篡改检测
└── FeatureNotAvailableException          功能不可用

CryptographyServices 工厂

// 创建签名器(颁发端)
ILicenseSigner signer = CryptographyServices.CreateSigner(privateKeyBytes);

// 创建签名验证器
ISignatureVerifier verifier = CryptographyServices.CreateSignatureVerifier(publicKeyBytes);

// 创建序列化器
ILicenseSerializer serializer = CryptographyServices.CreateSerializer();

错误码

分类编码规则

三位编码:百位 = 类别,十位 + 个位 = 序号

范围 类别
1xx 文件与 IO
2xx 加密与签名
3xx 许可证内容
4xx 原生签名验证
5xx 系统
6xx 参数与缓冲区

完整错误码

错误码 名称 说明
0 None 无错误
100 NoLicense 未找到许可证文件
101 Io 许可证文件读取失败
200 Decrypt 许可证文件解密失败
201 Sign 许可证签名验证失败
202 SignatureInvalid 许可证签名无效
300 Format 许可证格式无效
301 Hwid 机器码不匹配
302 Expired 许可证已过期
303 LicenseExpired 许可证已过期(Native 层)
304 FingerprintMismatch 机器指纹不匹配
305 InvalidLicenseFormat 许可证格式无效(Native 层)
400 NativeSignMismatch 原生签名不匹配
401 NativeDataInvalid 原生数据无效
402 NativeSignParamInvalid 原生签名参数无效
403 NativeMachineIdInvalid 原生机器码无效
404 NativeBase64DecodeFailed Base64 解码失败
405 NativeSpkiInvalid SPKI 公钥无效
410 NativeInternalError 原生内部错误
420 NativeDllUnavailable Native DLL 不可用
421 NativeSpkiPrecheckFailed SPKI 预检失败
430 NativeBridgeError C# 桥接层异常
500 Time 系统时间异常
501 Tamper 完整性校验失败
502 AuthenticodeFailed Authenticode 签名验证失败
503 SelfVerifyFailed DLL 自校验失败
504 HwReadFailed 硬件信息读取失败
505 TpmUnavailable TPM 不可用
506 NativeDebuggerDetected 原生层检测到调试器
599 Exception 未分类验证异常
600 BufferTooSmall 输出缓冲区太小
601 InvalidParam 参数无效
607 ProfilerDetected 检测到性能分析器

错误码扩展方法

var description = result.ErrorCode.GetDescription();  // 获取中文描述
var description = LicenseErrorCode.Exception.GetDescription("详情");  // 异常类错误码可传入详情

架构

ZLicense
├── Core/               领域模型、接口契约、枚举、异常
│   ├── Contracts/      接口定义(ILicenseManager, ILicenseCodec, ...)
│   ├── Models/         领域模型(License, LicensePayload, LicenseValidationResult, ...)
│   ├── Enums/          枚举(LicenseType, RequestType, LicenseErrorCode)
│   └── Exceptions/     异常层次(LicenseException 及其子类)
├── Cryptography/       加密原语
│   ├── ECDSA/          ECDSA 签名器(EcdsaSigner)
│   ├── Signatures/     签名验证适配器(SignatureVerifierAdapter)
│   └── CryptographyServices  加密服务门面(工厂方法)
├── Infrastructure/     基础设施(密钥辅助、加密辅助、Native DLL 哈希)
├── SDK/                业务入口
│   ├── SdkServiceRegistration  DI 服务注册扩展
│   ├── Runtime/        LicenseManager 实现
│   ├── Codec/          LicenseCodec 编解码器
│   ├── Fingerprint/    MachineFingerprintProvider
│   ├── Validation/     LicenseValidator
│   ├── Storage/        SecureStorage(DPAPI 加密)
│   ├── Tamper/         TamperDetector(时间回滚 + 哈希校验)
│   ├── Trial/          TrialManager(试用期管理)
│   ├── AuthGuard/      SDK 授权守卫(编译时 + 运行时验证)
│   ├── Native/         NativeLicenseBridge(P/Invoke 桥接层)
│   │   └── Wrappers/   Native 包装类(Native 优先 + 托管回退)
│   └── Guard/          ZLicenseGuardKeys(公钥与包 ID)
├── Native/             C++ 原生安全层
│   ├── Business/       业务逻辑(指纹、编解码、验证、注册表、安全存储、试用期)
│   ├── Crypto/         加密原语(AES、DPAPI、ECDSA、SHA-256)
│   ├── Security/       安全机制(反调试、Authenticode、防篡改)
│   └── Export/         导出函数(序号导出 #2 ~ #45)
├── build/              NuGet 包 MSBuild targets
│   └── ZLicense.targets  编译时授权验证 + Native DLL 复制
└── Polyfills/          netstandard2.0 兼容层

Native 安全层

NativeLicenseValidator.dll 是 ZLicense 的原生安全层,将关键验证逻辑下沉到 C++/Win32 层执行,避免 .NET 托管层被轻易反编译和篡改。

构建配置

属性
平台工具集 v145 (Visual Studio 2022)
目标平台 x64 only
字符集 Unicode
输出目录 Native\x64\
依赖库 bcrypt.lib, crypt32.lib
预处理器 NATIVELICENSEVALIDATOR_EXPORTS
导出方式 序号导出(#2 ~ #45),不导出符号名
导入库 不生成(/NOEXP / /NOIMPLIB
调试信息 Release 构建不生成 PDB

导出函数概览

序号 函数 说明
#2 NL_VerifyExeHash EXE 哈希验证
#3 NL_DetectDebugger 调试器检测
#4 NL_ValidateLicense 综合许可证验证
#5 NL_DeriveAesKey PBKDF2 密钥派生
#6 NL_MatchFingerprint 指纹匹配评分
#7 NL_DetectTamper 防篡改检测
#8 NL_ComputeFileHash 文件哈希计算
#9 NL_GetEntropy 随机熵源
#10 NL_SelfVerify DLL 自校验
#11 NL_VerifyAuthenticode Authenticode 验证
#12 NL_ReadDiskSerialNative 磁盘序列号读取
#13 NL_ReadBoardSerialNative 主板序列号读取
#14 NL_ReadTpmEkHash TPM EK 哈希读取
#15 NL_GenerateFingerprint 生成机器指纹
#16 NL_ValidateLicenseFull 完整许可证验证(含篡改检测)
#17 NL_ValidateLicenseFileNative 从文件验证许可证
#18 NL_AesEncrypt AES 加密
#19 NL_AesDecrypt AES 解密
#20 NL_DpapiProtect DPAPI 加密
#21 NL_DpapiUnprotect DPAPI 解密
#22 NL_Sha256 SHA-256 哈希(数据)
#23 NL_Sha256FileNative SHA-256 哈希(文件)
#24 ~ #28 NL_Storage* 安全存储(初始化/保存/加载/删除/检查)
#29 ~ #31 NL_Trial* 试用期管理(获取信息/启动/是否过期)
#32 NL_AntiDebugFullCheck 综合反调试检测
#33 ~ #34 NL_Serialize/DeserializeLicense 许可证序列化/反序列化
#35 NL_ExtractPayload 提取载荷
#36 NL_DeriveAesKeyNew 新格式 PBKDF2 密钥派生
#37 NL_DeriveAesKeyLegacy 旧格式双重 SHA-256 密钥派生
#38 ~ #39 NL_Registry*Encrypted 注册表加密读写
#40 NL_GetSelfVerifyHashSlot 自验证哈希槽地址
#41 ~ #42 NL_Read/WriteLicenseFileNative 许可证文件读写
#43 NL_CheckTimeIntegrity 时间完整性检查
#44 NL_RandomBytes 安全随机数生成
#45 NL_TrialRecordLaunch 试用期启动时间记录

指纹匹配权重

组件 权重
CPU 0.40
BIOS 0.30
主板 0.20
磁盘 0.10

完全匹配快速返回 1.0,否则按组件逐项加权计算。

防篡改检测位掩码

含义
bit0 (1) 时间回滚(当前时间比上次运行时间早超过 5 分钟)
bit1 (2) 许可证替换(哈希不一致)

安全机制

反调试保护

所有关键导出函数入口均调用 AntiDebugCheck(),通过 IsDebuggerPresent()CheckRemoteDebuggerPresent() 检测调试器附加,一旦检测到立即调用 TerminateProcess 终止进程。C# 桥接层额外实现了 IAT/EAT Hooking 检测(VerifyExportAddresses())。

SPKI 公钥完整性校验

VerifySpkiIntegrity() 对传入的 SPKI 公钥执行字节级结构验证:

  • 长度必须为 91 字节
  • 偏移 [0..2] 必须为 0x30 0x59(SEQUENCE)
  • 偏移 [2..4] 必须为 0x30 0x13(内层 SEQUENCE)
  • 偏移 [23..25] 必须为 0x03 0x42(BIT STRING)
  • 偏移 [25..27] 必须为 0x00 0x04(未压缩点标记)
DLL 自校验

构建时通过 inject-self-hash.ps1 将 DLL 的 SHA-256 哈希注入到 PE 文件的专用槽中,运行时 NL_SelfVerify() 重新计算哈希并与存储值比对,检测 DLL 是否被篡改。

链接器保护

Release 构建启用 /NOEXP 禁止导出导入库,GenerateDebugInformation 设为 false,防止通过导入库或 PDB 泄露符号信息。

与 C# 层的集成

  • C# 侧通过 NativeLicenseBridge 类使用 DllImport P/Invoke 调用本 DLL
  • 构建流程:ZLicense.csprojBuildNativeValidator Target 中通过 vswhere 定位 MSBuild 编译本项目
  • 产出物 NativeLicenseValidator.dll 通过 NuGet 包的 build\ZLicense.targets 在消费项目构建时自动复制到输出目录
  • 所有 Native 包装类采用 Native 优先 + 托管回退 策略,当 Native DLL 不可用时自动降级到托管实现

SDK 授权守卫

ZLicense 使用 SDKGuard 授权体系,确保只有获得授权的开发者才能使用本 SDK:

  1. 编译时验证ZLicense.targetsCoreCompile 之前检查 zlicense.auth.dll 的存在性、大小(224 字节)、魔数(ZLOG)、版本号和 PackageId
  2. 运行时验证SdkServiceRegistration.AddLicensingSdk() 调用 GuardValidator.Initialize() 验证授权 DLL 的 ECDSA 签名

授权文件搜索路径(按优先级):

  1. 项目根目录
  2. licenses/ 子目录
  3. License/ 子目录

混淆策略

Release 构建自动执行 Obfuscar 混淆,混淆后替换原始 DLL:

配置项 说明
KeepPublicApi false 所有类型均参与重命名
HidePrivateApi true 隐藏私有 API 标识符
HideStrings true 字符串加密
RenameProperties true 重命名属性
RenameEvents true 重命名事件
RenameFields true 重命名字段
UseUnicodeNames true 使用 Unicode 不可读字符重命名

保留的公共 API

以下命名空间和类型不参与混淆,确保消费者正常使用:

保留范围 原因
ZLicense.Core.Contracts 公共接口,消费者必须引用
ZLicense.Core.Enums 公共枚举
ZLicense.Core.Models 公共模型
ZLicense.Core.Exceptions 公共异常
ZLicense.SDK.SdkServiceRegistration SDK 入口类
ZLicense.SDK.Native P/Invoke 声明
ZLicense.SDK.Fingerprint 机器指纹提供者
ZLicense.Cryptography.Signatures 签名验证适配器
ZLicense.Cryptography.CryptographyServices 加密服务门面
Alone.SDKGuard 授权守卫共享源码
ZLicense.Polyfills 兼容层

运行要求

  • Windows x64
  • .NET 8.0+ 或 .NET Framework 4.6.2+(通过 netstandard2.0)
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated

Initial release with IsUniversal support, LicenseCodec, NativeLicenseBridge, and TamperDetector enhancements