# 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私钥,自己保存好,不要暴露给客户
```