I am working on rewriting this project in Rust to provide a safer and more streamlined license system. This will be a long-term project that I will maintain and will also serve as my graduation project (even though it's still quite early).
In any case, everything is under consideration and progress has already begun.
Anyway, I think it's time to open source this project. Some parts of the code are quite complex and messy, and I doubt anyone would want to maintain it.
In any case, if this project can be of help to you, it is my honor. For more details, you can check QuickStart. Any new bugs that arise during use will not be fixed.
This project will not receive any support, but I am still willing to review PRs and they are welcome.
CryptoVerifier 是一款高效而经济的许可证验证解决方案,我们专注于 尽力 保障您的软件许可证的安全性、完整性和合法性。借助多重加密、验证和防护措施,有效地防止许可证文件的伪造、滥用和非法复制等安全威胁。
我们为您提供灵活多样的许可证保护功能,涵盖硬件标识、IP限制、使用次数限制和并行限制等多种选择,确保多层次的安全措施轻松实现。同时,我们还提供简化许可证更新和过期处理的机制,满足您特定的需求。
- ⚙️ 自定义:我们提供了配置文件与非常多的开发者 API,您可以自定义命令、验证器、线程池、数据库,也可以进行事件监听等操作。我们同时确保产品在处理安全问题方面具备自动化能力。
- 👣 多重验证手段:为了确保许可证的安全性和完整性,我们提供了多种验证方式,包括文件解析验证、UUID 验证和哈希验证等,以提供更加多样化和可靠的验证手段。
- 🦾 自定义验证器: 我们提供了自定义验证器 API,使开发者能够根据自己的需求创建个性化的验证逻辑,并进行应急响应等操作,以满足特定的验证要求。
- 🎼 命令行:为了方便开发者使用许可证系统,我们提供了简洁易用的命令行工具,使其能够更便捷地进行操作。
- 📙 数据库:我们支持 MySQL、MongoDB 和 File 存储,并利用 Redis 对部分内容进行存储,以提供灵活的数据库选择和数据存储方案。
- 📊 日志记录:我们提供完善的日志记录功能,记录命令、许可证验证时间、返回信息、验证 IP 等信息,以帮助用户进行跟踪和分析。
- 🎲 加密算法:为确保许可证信息的保密性,我们使用多重加密对许可证进行加密,以保障敏感信息的安全性。
- 🔒 密钥交换:通过密钥交换协议,确保服务器返回的验证信息的完整性和真实性,以防止数据被篡改、伪造、重放攻击或者遭遇虚假验证服务器等安全威胁。
- 🎳 使用限制:我们支持多种用户使用限制,如硬件标识 (HWID)、IP、使用次数、并行限制等,以防止滥用问题的发生。
- 🕒 时间限制:我们提供根据时间限制设置许可证的有效期,以确保许可证在指定时间段内有效,并对其过期时间进行控制。
- 💨 性能优化:通过缓存机制大幅提高验证性能,在多次验证时的速度得到显著提升,提供更好的用户体验。
- 🚦 临时封禁:我们支持临时封禁和解封许可证的功能,以在特殊情况下限制许可证的使用,确保系统安全。
- 🧬 文件追踪:我们支持通过许可证文件追踪到具体用户,以便在许可证文件泄露时能够采取相应的限制措施,加强安全保护。
- 🖥️ 集群支持:我们支持多验证服务器集群,以确保用户能够使用具有最佳延迟的服务器,提供更快速、稳定的服务体验。
- ✍️ 示例项目:我们提供了详细的示例代码和集成指南,帮助开发者轻松地将许可证系统集成到他们的项目中,开始插件的开发,降低开发难度和时间成本。
CryptoVerifier 提供高度自定义的配置,允许用户根据其业务需求对系统进行定制,使其适应不同的应用场景和要求。
CryptoVerifier 允许您自定义线程池,以更好的满足高并发场景。
# 验证服务端口
PORT: 17354
# 线程池设置
THREAD-POOL:
# 核心线程数
# 定义线程池中始终保持活动的线程数量
# 这些线程会一直存在,即使它们处于空闲状态,也不会被回收
# 将核心线程数设置为处理器核心数的 1 倍到 2 倍之间可以有效利用资源,但实际的最佳值会因系统负载而有所不同
# 使用 max 将设置为 Integer.MAX_VALUE
CORE-POOL-SIZE: 8
# 最大线程数
# 定义线程池中允许存在的最大线程数量。
# 当线程池中的活动线程数已经达到了核心线程数,而仍然有新的任务提交到线程池时,线程池会创建新的线程来处理这些任务,直到线程数达到最大线程数
# 一般情况下,将最大线程数设置为核心线程数的 2 倍是常见的做法,但需要根据具体情况进行调整
# 使用 max 将设置为 Integer.MAX_VALUE
MAX-POOL-SIZE: 16
# 非核心线程的空闲时间(毫秒)
# 当线程池中的线程数超过核心线程数,并且空闲一段时间后,多余的线程会被回收
# 这个时间间隔即为空闲线程的存活时间
KEEP-ALIVE-TIME: 60000
# 任务队列的容量
# 用于存储等待执行的任务的队列的最大容量
# 当线程池的活动线程数达到核心线程数时,后续的任务将被放入任务队列中等待执行
# 使用 max 将设置为 Integer.MAX_VALUE
QUEUE-CAPACITY: 100
CryptoVerifier 支持集群,并支持您使用 MongoDB、MySQL、File 方式对数据进行存储,这一切都是加密的。
# Redis 数据库设置 (必须使用)
REDIS:
IP: 127.0.0.1
PORT: 6379
AUTH:
USER: ""
PASSWORD: ""
CUSTOM-URL: ""
# 数据存储类型,服务端数据是使用文件存储还是数据库,MongoDB、MySQL、File
# 注意,如果您需要使用集群功能,则必须使用数据库来保证数据同步,否则会出现错误
DATA-STORAGE-TYPE: "File"
# Mongo 数据库设置
MONGO:
IP: 127.0.0.1
PORT: 27017
# 使用用户名或密码 (若没有设置用户密码则两个都不填写)
AUTH:
USER: ""
PASSWORD: ""
# 自定义 Mongo 连接 URL
# 如果启用则需要自己写连接 URL,上面的指定内容全部作废,数据库名: CryptoVerifier
# 示例: mongodb://USER:PWD@IP:PORT/CryptoVerifier - 使用用户密码登陆指定服务器的 CryptoVerifier 数据库
CUSTOM-URL: ""
# MySQL 数据库设置 (使用 MySQL 记得新建 CryptoVerifier 库)
MYSQL:
# MySQL5 使用: com.mysql.jdbc.Driver
# MySQL8 使用: com.mysql.cj.jdbc.Driver
DRIVER: com.mysql.cj.jdbc.Driver
IP: 127.0.0.1
PORT: 3306
AUTH:
USER: ""
PASSWORD: ""
CUSTOM-URL: ""
CryptoVerifier 支持通过配置文件更加简单的对返回值进行修改,简单的修改完全不必依赖于 API.
# 自定义返回结果
# 默认配置是安全的,且给出的客户端示例兼容的,如果您需要更改此项那么请注意客户端适配。
#
# 开发者可以拆分结果,验证通过后将用户信息打印至控制台等,让用户知道更多关于自己许可证的信息,如过期时间等
#
# 我们不建议您修改所有的返回信息,这可能会导致用户信息泄露。
# 我们只建议您在验证通过、被封禁、被限制 (IP HWID 验证次数 并行)、过期等特殊情况下提供相应信息以便了解情况。
#
# 不支持: UNKNOWN FILE_ERROR FILE_NOT_FOUND_ERROR,因为这些情况我们无法获得许可证信息
#
# 支持变量: <uuid> <ip> <hwid> <extraData> <isTempBanned> <tempBannedInfo>
# <hwidLimit> <hwidAmount> <ipLimit> <ipAmount> <verificationLimit>
# <verificationTimes> <parallelLimit> <creationDate> <verificationInfo>
# <expirationDate>
CUSTOM-RESULT:
TEMP_BANNED: "BANNED|<tempBannedInfo>"
SUCCESS: "SUCCESS|<uuid>|<expirationDate>|<verificationInfo>"
CryptoVerifier 提供以简洁为主的 API。您可以轻松实现许可证的生成、自定义验证和更新,也可以实现自定义的验证或返回逻辑,甚至远程类加载,以及其他相关的操作。我们的开发指南提供了清晰的步骤和示例代码,帮助您快速上手开发插件。
/**
* 验证器接口,所有验证器类都应实现此接口,并重写所有方法。
*
* @author 2000000
* @version 1.1
* @since 2023/7/14
*/
public interface Validator {
/**
* 验证方法。
*
* <p>
* 注意,此处的 {@code serverVerifierDataObject} 会持续更新,
* 保证下一个验证器收到的是上一个验证器返回的最新数据。但真正的 IO 操作只有所有验证通过才会进行。
* </p>
*
* @param ip 客户端 IP 地址
* @param credentialData 凭证数据对象
* @param clientVerifierDataObject 客户端验证数据对象
* @param serverVerifierDataObject 服务器验证数据对象
* @return 验证结果
*/
boolean validate(String ip, CredentialData credentialData, Object clientVerifierDataObject, Object serverVerifierDataObject) throws Exception;
/**
* 权重,越低越先执行。
*
* <p>
* 范围在 {@code 20} ~ {@code 10000} 之间。
* </p>
*
* <p>
* 虽然您可以注册 {@code 20} 以下的权重,但是为了安全期间,我永远不会推荐您这么做,除非您真的知道自己在做什么。
* </p>
*
* @return 权重
*/
int getWeight();
/**
* 是否忽略异常。
*
* <p>
* 若为真,当 {@link Validator#validate(String, CredentialData, Object, Object)} )} 出现异常时直接返回 {@link Validator#getFailedMessage()},否则将打印异常后返回。
* </p>
*
* @return 是否忽略异常
*/
boolean isIgnoreException();
/**
* 验证器名称。此项不能为空。
*
* @return 验证器名称
*/
@NonNull
String getName();
/**
* 验证失败时返回的信息。此项不能为空。
*
* <p>
* 我们支持您根据不同的条件在此处返回不同的信息,但这种动态返回仅支持此方法与 {@link Validator#getServerVerifierData()} 方法。
* 其余方法动态返回将是不安全且不推荐的做法。
* </p>
*
* @return 验证失败时返回的信息
*/
@NonNull
String getFailedMessage();
/**
* 对于此验证器的描述。
*
* @return 描述
*/
String getDescription();
/**
* 服务器验证数据。
*
* <p>
* 当您尝试修改了服务器验证数据时,这里必须为您修改后的对象,否则将不会有 IO 操作。
* </p>
*
* <p>
* 若为 {@code null} 则为未进行修改,若未空 {@code ""} 则未删除该用户的数据。
* </p>
*
* @return 服务器验证数据
*/
Object getServerVerifierData();
}
ValidatorManager.getValidatorManager().registerValidator(new ExampleValidation());
LoggerUtils.getLogger().info("[ExamplePlugin] 自定义验证器已成功注册!");
不仅仅是验证器,您还可以写属于您自己的命令操作。
/**
* 定义命令接口。
*
* @author 2000000
* @version 1.0
* @since 2023/8/27
*/
@SuppressWarnings("unused")
public interface Command {
/**
* 处理命令。
*
* <p>
* 格式为: {@code main sub sub},该方法将获取到 {@code sub sub} 数组。
* </p>
*/
void handleCommand(String[] args) throws Exception;
/**
* 获取主命令。
*
* <p>
* 格式为: {@code main sub sub},该方法将获取 {@code main} 字段。
* </p>
*
* @return 主命令
*/
String getMainCommand();
/**
* 对于此命令的描述。
*
* @return 描述
*/
String getDescription();
/**
* 获取命令执行线程。
*
* @return 获取命令执行线程
*/
default Thread getThread() {
return Thread.currentThread();
}
}
使用事件监听器,简单的对操作内容进行干预。
/**
* 一个简单的示例事件监听类,事件监听类应实现 {@link Listener} 接口。
*
* <p>
* 事件请查看 {@link twomillions.other.cryptoverifier.events.custom} 软件包下所有类。
* </p>
*
* @author 2000000
* @version 1.0
* @since 2023/7/2
*/
@SuppressWarnings("unused")
public class ExampleListener implements Listener {
/**
* 事件监听器,处理事件。
* 必须使用 {@link EventHandler} 注解,否则无效。
*
* @param event 初始化完成事件
*/
@EventHandler
public void testEventHandler(InitializationCompleteEvent event) {
Logger logger = LoggerUtils.getLogger();
logger.info("--------------------");
logger.info("出现这条消息代表已经成功触发 InitializationCompleteEvent, 这与 Bukkit Event 类似。");
logger.info("我们不建议使用 System.out.println 打印日志信息, 在高并发情况下效率极低。");
logger.info("我们推荐使用日志依赖库, 您可以使用 LoggerUtils.getLogger() 获取 Logger 打印日志。");
logger.info("--------------------");
logger.info("大多数事件都是异步的, 此处为初始化完成事件, 为同步事件, 可使用 isSync() 检查是否为同步事件。");
logger.info("可使用线程池 VerifierThreadPool.getVerifierThreadPool() 进行同步、异步、延迟、重复操作, 与 Bukkit 线程池类似。");
logger.info("--------------------");
logger.info("是否同步: " + event.isSync());
logger.info("线程名称: " + event.getThread().getName());
logger.info("--------------------");
/*
* 使用 CommandManager.getCommandManager().callCommand(String) 方法处理命令
*/
CommandManager.getCommandManager().callCommand("help");
}
}
CryptoVerifier 提供完善的日志记录功能,记录命令、许可证验证时间、返回信息、验证 IP 等信息,以帮助用户进行跟踪和分析。
[2023/07/18 19:01:00] [INFO]: [Socket] [User1] [xxx.xxx.xxx.xxx] 验证完成, 处理结果: SUCCESS
[2023/07/18 19:01:00] [INFO]: [Socket] [User1] [xxx.xxx.xxx.xxx] 即将断开连接, 本次验证耗时: 125ms
[2023/07/18 19:01:22] [INFO]: 即将清除所有的 IP 黑名单, 在过去的一分钟之内请求状况如下:
[2023/07/18 19:01:22] [INFO]: IP: xxx.xxx.xxx.xxx, 请求次数: 1
[2023/07/18 19:06:22] [INFO]: [Socket] [User2] [xxx.xxx.xxx.xxx] 验证完成, 处理结果: SUCCESS
[2023/07/18 19:06:22] [INFO]: [Socket] [User2] [xxx.xxx.xxx.xxx] 即将断开连接, 本次验证耗时: 110ms
[2023/07/18 19:06:22] [INFO]: 即将清除所有的 IP 黑名单, 在过去的一分钟之内请求状况如下:
[2023/07/18 19:06:22] [INFO]: IP: xxx.xxx.xxx.xxx, 请求次数: 1
[2023/07/18 19:11:29] [INFO]: [Socket] [User3] [xxx.xxx.xxx.xxx] 验证完成, 处理结果: SUCCESS
[2023/07/18 19:11:29] [INFO]: [Socket] [User3] [xxx.xxx.xxx.xxx] 即将断开连接, 本次验证耗时: 122ms
[2023/07/18 19:12:08] [INFO]: [Socket] [User4] [xxx.xxx.xxx.xxx] 验证完成, 处理结果: SUCCESS
[2023/07/18 19:12:08] [INFO]: [Socket] [User4] [xxx.xxx.xxx.xxx] 即将断开连接, 本次验证耗时: 128ms
[2023/07/18 19:12:22] [INFO]: 即将清除所有的 IP 黑名单, 在过去的一分钟之内请求状况如下:
[2023/07/18 19:12:22] [INFO]: IP: xxx.xxx.xxx.xxx, 请求次数: 1
[2023/07/18 19:12:22] [INFO]: IP: xxx.xxx.xxx.xxx, 请求次数: 1
[2023/07/18 19:35:22] [INFO]: [Socket] [User7] [xxx.xxx.xxx.xxx] 验证完成, 处理结果: SUCCESS
[2023/07/18 19:35:22] [INFO]: [Socket] [User7] [xxx.xxx.xxx.xxx] 即将断开连接, 本次验证耗时: 114ms
[2023/07/18 19:36:22] [INFO]: 即将清除所有的 IP 黑名单, 在过去的一分钟之内请求状况如下:
[2023/07/18 19:36:22] [INFO]: IP: xxx.xxx.xxx.xxx, 请求次数: 1
CryptoVerifier 通过缓存机制大幅提高验证性能,在多次验证时的速度得到显著提升,提供更好的用户体验,快速且安全的毫秒级验证。
[2023/07/18 19:01:00] [INFO]: [Socket] [User1] [xxx.xxx.xxx.xxx] 验证完成, 处理结果: SUCCESS
[2023/07/18 19:01:00] [INFO]: [Socket] [User1] [xxx.xxx.xxx.xxx] 即将断开连接, 本次验证耗时: 125ms
[2023/07/18 19:06:22] [INFO]: [Socket] [User2] [xxx.xxx.xxx.xxx] 验证完成, 处理结果: SUCCESS
[2023/07/18 19:06:22] [INFO]: [Socket] [User2] [xxx.xxx.xxx.xxx] 即将断开连接, 本次验证耗时: 110ms
[2023/07/18 19:11:29] [INFO]: [Socket] [User3] [xxx.xxx.xxx.xxx] 验证完成, 处理结果: SUCCESS
[2023/07/18 19:11:29] [INFO]: [Socket] [User3] [xxx.xxx.xxx.xxx] 即将断开连接, 本次验证耗时: 122ms
[2023/07/18 19:12:08] [INFO]: [Socket] [User4] [xxx.xxx.xxx.xxx] 验证完成, 处理结果: SUCCESS
[2023/07/18 19:12:08] [INFO]: [Socket] [User4] [xxx.xxx.xxx.xxx] 即将断开连接, 本次验证耗时: 128ms
[2023/07/18 19:35:22] [INFO]: [Socket] [User7] [xxx.xxx.xxx.xxx] 验证完成, 处理结果: SUCCESS
[2023/07/18 19:35:22] [INFO]: [Socket] [User7] [xxx.xxx.xxx.xxx] 即将断开连接, 本次验证耗时: 114ms
- CryptoVerifier 采用多重加密手段对许可证文件进行加密,并使用动态加密技术对配置密钥进行加密存储,以确保许可证文件的数据安全性。
- CryptoVerifier 使用多层加密措施,包括对许可证文件和配置密钥的加密,以提供更高的数据保护级别。
- CryptoVerifier 采用多重加密和验证手段,防止许可证文件被伪造。此外,它提供了多种功能,如硬件标识 (HWID)、IP、使用次数和并行限制等,以防止许可证的滥用问题。
- CryptoVerifier 支持对已有许可证进行更新。开发者可以使用 CryptoVerifier 提供的命令行工具来更改许可证的参数,例如重置硬件标识 (HWID)、IP 或更改限制次数等。
- 对于过期的许可证,CryptoVerifier 提供了自定义选项,开发者可以根据需求进行配置,选择是删除过期许可证还是保留它。
CryptoVerifier 是专为 Java 平台设计的许可证保护系统,您可以用它保护 Java 程序、Minecraft 插件、Minecraft 模组等,您也可以使用 API 来拓展功能适应您目前的使用环境。
CryptoVerifier 的主要目标是在网络验证过程中提供安全保护,而并非致力于提供针对字节码级别的代码保护。对于代码保护需求,建议使用其他专门的工具和技术,以确保您的代码在字节码级别的安全性。
尽管 CryptoVerifier 提供了多种功能,但仍需注意以下事项:
- CryptoVerifier 提供了多重保护措施,但安全性并不完全依赖于它。它仅在其控制范围内尽力提供安全性
- 如果您的 Java 文件可以被反编译后阅读,黑客仍然可能绕过 CryptoVerifier 的保护。如果黑客具备足够的技术支持攻克您的混淆代码**,CryptoVerifier 将无法提供绝对保护**。
请注意,安全性不仅取决于 CryptoVerifier,还取决于您采取的其他安全措施和实施的最佳实践,它并不能保证百分之百的安全,它只是为了 尽量 保护软件免受盗版、非法复制和滥用等威胁。
要顺利使用 CryptoVerifier,了解 Java 基础知识并能够理解 Java 文档 (JavaDoc) 是必要的。以下是一些需要掌握的基本要求:
- Java 编程语言: CryptoVerifier 是专为 Java 平台设计的许可证保护系统,因此熟悉 Java 语法、关键字、面向对象编程和基本的多线程编程概念是必要的。
- JavaDoc 阅读能力: JavaDoc 是 Java 官方的文档注释工具,它提供了对类、方法、字段等的说明和文档,您必须理解 JavaDoc 才能够使用 API 开始开发插件。