# springboot-license **Repository Path**: sky061015/springboot-license ## Basic Information - **Project Name**: springboot-license - **Description**: springboot web项目授权码授权和管理 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2024-09-05 - **Last Updated**: 2025-10-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

一个基于springboot项目的license授权管理starter项目

springboot-license项目主要基于JDK自带的证书生成工具**keytool**结合绑定服务器硬件相关参数实现一机一证书的授权模式,实现软件授权,该start主要为springboot为基础的web服务提供授权管理,所以该项目实现主要技术路线为springboot技术栈,整个项目分为授权认证starter模块和授权证书管理模块,基本实现开箱即用的原则。 ​ 之前项目因为么有采用复杂的软件授权逻辑,导致项目授权到期后客户采用暴力破解或者跳过认证的方式,跳过了license的授权管控,导致项目尾款无法结算,以此为初衷特地写了这个插件,特定将groupId命名为org.springframework为前缀是为了让技术人员无法找到代码路径,当然,如果用户有源码仍然会破解,所以各位兄弟在拿到尾款前,切勿将源码拷贝到客户的任何机器,这些都是我躺过来的坑.😭😭😭 ### 实现原理 ```apl 软件采用springboot的starter原理,实现开箱即用,方便大家实现授权管理. 实现原理主要采用拦截器+物理机器ip、mac、cpu序列,主板型号等参数+授权证书的截止日期实现授权合法验证。整体技术并不复杂,切记不能向客户暴露密钥密码和密钥文件。 ``` ### 演示地址 ```apl ``` ### 使用说明 本地引用starter, 将代码下载后,通过maven的install将start插件安装到本地maven repository, 通过一下manven坐标引入到项目: ```xml org.springframework.license spring-boot-license-starter 1.0 ``` 在springboot项目中注入拦截器: ```java package com.tiankong.visitor.framework.configure; import org.springframework.context.annotation.Configuration; import org.springframework.license.interceptor.LicenseInterceptor; import org.springframework.web.servlet.config.annotation.*; @Configuration public class WebIndexConfig implements WebMvcConfigurer { ... /** * 注入拦截器 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { WebMvcConfigurer.super.addInterceptors(registry); registry.addInterceptor(new LicenseInterceptor()).addPathPatterns("/**"); } ... } ``` 使用keytool生成私钥和公钥: ------ keytool密钥命令参数说明 | 参数名称 | 参数说明 | 备注 | | --------- | ---------------------------------------- | ------------------------------------------------------------ | | keysize | 密钥长度 | 建议使用1024 | | keyalg | 加密方式 | | | validity | 私钥的有效期(单位:天) | 建议设置为3650天,也就是10年. | | alias | 私钥别称 | 自定义建议用字母组成 | | keystore | 指定私钥库文件的名称 (生成在当前目录) | | | storepass | 指定私钥库的密码 (keystore 文件存储密码) | 该密码请妥善保管,切勿暴露给客户方,同时密钥也不可暴露 | | keypass | 指定别名条目的密码 (私钥加解密密码) | | | dname | 证书个人信息 | CN 为你的姓名
OU 为你的组织单位名称
O 为你的组织名称
L 为你所在的城市名称
ST 为你所在的省份名称
C 为你的国家名称 | 1. 生成密钥 ```apl keytool -genkey -keysize 1024 -keyalg DSA -validity 3650 -alias "privateKey" -keystore "privateKeys.keystore" -storepass "password" -keypass "password" -dname "CN=localhost, OU=localhost, O=localhost, L=HN, ST=HN, C=CN" ``` 2. 导出命令 ```apl keytool -exportcert -alias "privateKey" -keystore "privateKeys.keystore" -storepass "password" -file "certfile.cer" ``` 3. 导入命令 ```apl keytool -import -alias "publicCert" -file "certfile.cer" -keystore "publicCerts.keystore" -storepass "password" ``` 4. 生成授权证书 生成证书需要获取到客户所部署的服务上后获取,证书参数需要通过物理机器ip、mac、cpu序列,主板型号等参数实现一机一证书,所以提供了获取服务器硬件参数的接口,目前只支持window和liunx两种操作系统 生成证书 ```java package org.springframework.license; import com.alibaba.fastjson.JSONObject; import org.springframework.license.service.AbstractComputerService; import org.springframework.license.service.LicenseCreator; import org.springframework.license.vo.Computer; import org.springframework.license.vo.LicenseCreatorParam; import java.io.File; /** * @Title Test * @Author zhijun.Guo * @Email tiankong061015@163.com * @Time 2024/9/2 23:28 * @Description */ public class Test { /** * 获取服务器硬件参数 */ @org.junit.jupiter.api.Test public void test1(){ Computer computer = AbstractComputerService.generateComputerInformation(); System.out.println(computer); } /** * 生成证书接口 */ @org.junit.jupiter.api.Test public void test2(){ LicenseCreatorParam param = new LicenseCreatorParam(); //TODO: 注入相关参数 LicenseCreator licenseCreator = new LicenseCreator(param); boolean result = licenseCreator.generateLicense(); System.out.println(param); } } ``` Computer参数如下: ```java package org.springframework.license.vo; import com.alibaba.fastjson.JSONObject; import lombok.Data; import java.io.Serializable; import java.util.List; /** * @Title 计算机信息 * @Author zhijun.Guo * @Email tiankong061015@163.com * @Time 2024/9/2 20:36 * @Description */ @Data public class Computer implements Serializable { /** * ip */ private List ip; /** * mac */ private List mac; /** * cpu型号 */ private String cpu; /** * 主板型号 */ private String mainBoard; @Override public String toString(){ return JSONObject.toJSONString(this); } } ``` LicenseCreatorParam参数如下: ```java package org.springframework.license.vo; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import java.io.Serializable; import java.util.Date; /** * @Title LicenseCreator * @Author zhijun.Guo * @Email tiankong061015@163.com * @Time 2024/9/2 20:53 * @Description */ @Data public class LicenseCreatorParam implements Serializable { /** * 证书subject */ private String subject; /** * 密钥别称 */ private String privateAlias; /** * 密钥密码(需要妥善保管,不能让使用者知道) */ private String keyPass; /** * 访问秘钥库的密码 */ private String storePass; /** * 证书生成路径 */ private String licensePath; /** * 密钥库存储路径 */ private String privateKeysStorePath; /** * 证书生效时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date issuedTime = new Date(); /** * 证书失效时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date expiryTime; /** * 用户类型 */ private String consumerType = "user"; /** * 用户数量 */ private Integer consumerAmount = 1; /** * 描述信息 */ private String description = ""; /** * 额外的服务器硬件校验信息 */ private Computer computer = new Computer(); @Override public String toString() { return JSONObject.toJSONString(this); } } ``` 运行成功后,会在指定目录生成license.lic文件,该文件则为授权证书,上传到服务器指定目录后,完成软件授权. 文件说明: ```apl license.lic和publicCerts.keystore两个文件放到客户指定服务器的目录,完成授权 certfile.cer导入完成后可以删除 privateKeys.keystore私钥,自己保存好,不要暴露给客户 ```