+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.continew.license.model;
+
+import net.lingala.zip4j.ZipFile;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 生成创建者返回参数
+ *
+ * @author echo
+ * @since 2.11.0
+ **/
+public class BuildCreatorResp implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 许可证创建者参数
+ */
+ private LicenseCreatorParam param;
+
+ /**
+ * 客户端zip文件
+ */
+ private ZipFile clientZipFile;
+
+ public BuildCreatorResp(LicenseCreatorParam param, ZipFile clientZipFile) {
+ this.param = param;
+ this.clientZipFile = clientZipFile;
+ }
+
+ public BuildCreatorResp() {
+ }
+
+ public LicenseCreatorParam getParam() {
+ return param;
+ }
+
+ public void setParam(LicenseCreatorParam param) {
+ this.param = param;
+ }
+
+ public ZipFile getClientZipFile() {
+ return clientZipFile;
+ }
+
+ public void setClientZipFile(ZipFile clientZipFile) {
+ this.clientZipFile = clientZipFile;
+ }
+}
diff --git a/continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/dto/ConfigParam.java b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/ConfigParam.java
similarity index 90%
rename from continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/dto/ConfigParam.java
rename to continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/ConfigParam.java
index 9f9d3331..2c06d2fd 100644
--- a/continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/dto/ConfigParam.java
+++ b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/ConfigParam.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package top.continew.license.dto;
+package top.continew.license.model;
/**
- * @Desc:
- * @Author loach
- * @ClassName top.continew.license.dto.ConfigParam
- * @Date 2025-03-21 14:50
- */
+ * config参数
+ *
+ * @author loach
+ * @since 2.11.0
+ **/
public class ConfigParam {
/**
diff --git a/continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/keyStoreParam/CustomKeyStoreParam.java b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/CustomKeyStoreParam.java
similarity index 76%
rename from continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/keyStoreParam/CustomKeyStoreParam.java
rename to continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/CustomKeyStoreParam.java
index f91a5e8e..da3e37a6 100644
--- a/continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/keyStoreParam/CustomKeyStoreParam.java
+++ b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/CustomKeyStoreParam.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package top.continew.license.keyStoreParam;
+package top.continew.license.model;
import de.schlichtherle.license.AbstractKeyStoreParam;
@@ -23,24 +23,37 @@ import java.io.IOException;
import java.io.InputStream;
/**
- * @Desc:
- * @Author loach
- * @ClassName top.continew.license.keyStoreParam.CustomKeyStoreParam
- * @Date 2025-04-12 14:50
+ * 自定义密钥存储参数
+ *
+ * @author loach
+ * @author echo
+ * @since 2.11.0
*/
public class CustomKeyStoreParam extends AbstractKeyStoreParam {
- /** 密钥路径,可为磁盘路径,也可为项目资源文件里的路径,如果为磁盘路径需重写getStream()方法 */
+ /**
+ * 密钥路径,可为磁盘路径,也可为项目资源文件里的路径,如果为磁盘路径需重写getStream()方法
+ */
private String storePath;
- /** 公钥或私钥的别名 */
+ /**
+ * 公钥或私钥的别名
+ */
private String alias;
- /** 访问公钥/私钥库的密码 */
+ /**
+ * 访问公钥/私钥库的密码
+ */
private String storePass;
- /** 公钥/私钥的密码 */
+ /**
+ * 公钥/私钥的密码
+ */
private String keyPass;
+ public CustomKeyStoreParam(Class aClass, String s) {
+ super(aClass, s);
+ }
+
public CustomKeyStoreParam(Class clazz, String resource, String alias, String storePass, String keyPass) {
super(clazz, resource);
this.storePath = resource;
diff --git a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/dto/LicenseCreatorParam.java b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/LicenseCreatorParam.java
similarity index 87%
rename from continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/dto/LicenseCreatorParam.java
rename to continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/LicenseCreatorParam.java
index 21c17182..b5822f62 100644
--- a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/dto/LicenseCreatorParam.java
+++ b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/LicenseCreatorParam.java
@@ -14,42 +14,56 @@
* limitations under the License.
*/
-package top.continew.license.dto;
+package top.continew.license.model;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
- * @Desc:
- * @Author loach
- * @ClassName top.continew.license.dto.LicenseCreatorParam
- * @Date 2025-03-21 14:22
- */
+ * 许可证创建者参数
+ *
+ * @author loach
+ * @since 2.11.0
+ **/
public class LicenseCreatorParam implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
- /** 证书主题 */
+ /**
+ * 证书主题
+ */
private String subject;
- /** 私钥别称 */
+ /**
+ * 私钥别称
+ */
private String privateAlias;
- /** 私钥密码 */
+ /**
+ * 私钥密码
+ */
private String keyPass;
- /** 访问公钥库的密码 */
+ /**
+ * 访问公钥库的密码
+ */
private String storePass;
- /** 证书生成路径 */
+ /**
+ * 证书生成路径
+ */
private String licensePath;
- /** 私钥库存储路径 */
+ /**
+ * 私钥库存储路径
+ */
private String privateKeysStorePath;
- /** 证书生效时间 */
+ /**
+ * 证书生效时间
+ */
private Date issuedTime = new Date();
/**
@@ -67,10 +81,14 @@ public class LicenseCreatorParam implements Serializable {
*/
private Integer consumerAmount = 1;
- /** 描述信息 */
+ /**
+ * 描述信息
+ */
private String description;
- /** 额外的服务器硬件校验信息 */
+ /**
+ * 额外的服务器硬件校验信息
+ */
private LicenseExtraModel licenseExtraModel;
public String getSubject() {
diff --git a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/dto/LicenseCreatorParamVO.java b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/LicenseCreatorParamVO.java
similarity index 94%
rename from continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/dto/LicenseCreatorParamVO.java
rename to continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/LicenseCreatorParamVO.java
index 137834a8..d7cfd2b0 100644
--- a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/dto/LicenseCreatorParamVO.java
+++ b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/LicenseCreatorParamVO.java
@@ -14,18 +14,16 @@
* limitations under the License.
*/
-package top.continew.license.dto;
+package top.continew.license.model;
import java.util.Date;
/**
* 为用户生成证书需要的具体参数
*
- * @Desc:
- * @Author loach
- * @ClassName top.continew.license.dto.LicenseCreatorParamVO
- * @Date 2025-03-21 14:29
- */
+ * @author loach
+ * @since 2.11.0
+ **/
public class LicenseCreatorParamVO {
/**
@@ -58,14 +56,6 @@ public class LicenseCreatorParamVO {
*/
private String licenseSavePath;
- public String getLicenseSavePath() {
- return licenseSavePath;
- }
-
- public void setLicenseSavePath(String licenseSavePath) {
- this.licenseSavePath = licenseSavePath;
- }
-
/**
* 额外的服务器硬件校验信息
*/
@@ -111,6 +101,14 @@ public class LicenseCreatorParamVO {
this.description = description;
}
+ public String getLicenseSavePath() {
+ return licenseSavePath;
+ }
+
+ public void setLicenseSavePath(String licenseSavePath) {
+ this.licenseSavePath = licenseSavePath;
+ }
+
public LicenseExtraModel getLicenseExtraModel() {
return licenseExtraModel;
}
diff --git a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/dto/LicenseExtraModel.java b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/LicenseExtraModel.java
similarity index 92%
rename from continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/dto/LicenseExtraModel.java
rename to continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/LicenseExtraModel.java
index 63cfcce3..4d591f56 100644
--- a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/dto/LicenseExtraModel.java
+++ b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/model/LicenseExtraModel.java
@@ -14,18 +14,16 @@
* limitations under the License.
*/
-package top.continew.license.dto;
+package top.continew.license.model;
import java.util.Set;
/**
* 额外的服务器硬件校验信息对象,这里的属性可根据需求自定义
*
- * @Desc:
- * @Author loach
- * @ClassName top.continew.license.dto.LicenseExtraModel
- * @Date 2025-03-21 14:28
- */
+ * @author loach
+ * @since 2.11.0
+ **/
public class LicenseExtraModel {
/**
diff --git a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/util/ExecCmdUtil.java b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/util/ExecCmdUtil.java
similarity index 88%
rename from continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/util/ExecCmdUtil.java
rename to continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/util/ExecCmdUtil.java
index ea6fb98a..b1823f36 100644
--- a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/util/ExecCmdUtil.java
+++ b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/util/ExecCmdUtil.java
@@ -16,21 +16,19 @@
package top.continew.license.util;
+import cn.hutool.core.util.ArrayUtil;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
-import cn.hutool.core.util.ArrayUtil;
-
/**
* 运行命令行工具类
*
- * @Desc:
- * @Author loach
- * @ClassName top.continew.license.util.ExecCmdUtil
- * @Date 2025-03-22 18:44
- */
+ * @author loach
+ * @since 2.11.0
+ **/
public class ExecCmdUtil {
private static final String CREATE_3RDSESSION_SHELL_SCRIPT = "head -n 80 /dev/urandom | tr -dc A-Za-z0-9 | head -c 168";
@@ -42,8 +40,8 @@ public class ExecCmdUtil {
* @return String 返回打印信息
*/
public static String exec(String... cmd) throws IOException {
- Process process = null;
- if (System.getProperty("os.name").indexOf("Windows") != -1) {
+ Process process;
+ if (System.getProperty("os.name").contains("Windows")) {
if (cmd != null && cmd.length == 1) {
process = Runtime.getRuntime().exec(cmd[0]);
} else {
@@ -59,6 +57,12 @@ public class ExecCmdUtil {
return print + " " + err;
}
+ /**
+ * 读取 InputStream 内容为字符串(使用 GBK 编码)。
+ *
+ * @param in 输入流
+ * @return 拼接后的字符串,读取失败返回空字符串
+ */
private static String readProcess(InputStream in) {
try (LineNumberReader print = new LineNumberReader(new InputStreamReader(in, "GBK"))) {
StringBuffer sb = new StringBuffer();
diff --git a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/util/ServerInfoUtils.java b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/util/ServerInfoUtils.java
similarity index 85%
rename from continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/util/ServerInfoUtils.java
rename to continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/util/ServerInfoUtils.java
index 89a85fa6..7a424698 100644
--- a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/util/ServerInfoUtils.java
+++ b/continew-starter-license/continew-starter-license-core/src/main/java/top/continew/license/util/ServerInfoUtils.java
@@ -23,8 +23,8 @@ import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import top.continew.license.dto.LicenseExtraModel;
import top.continew.license.exception.LicenseException;
+import top.continew.license.model.LicenseExtraModel;
import java.io.*;
import java.net.InetAddress;
@@ -39,7 +39,7 @@ import java.util.stream.Collectors;
* 服务器信息工具类
*
* @author Rong.Jia
- * @date 2022/03/10
+ * @since 2.11.0
*/
public class ServerInfoUtils {
@@ -55,7 +55,7 @@ public class ServerInfoUtils {
/**
* 组装需要额外校验的License参数
*
- * @return
+ * @return {@link LicenseExtraModel }
*/
public static LicenseExtraModel getServerInfos() {
LicenseExtraModel result = new LicenseExtraModel();
@@ -75,7 +75,7 @@ public class ServerInfoUtils {
/**
* 初始化服务器硬件信息,并将信息缓存到内存
*
- * @throws Exception 默认异常
+ * @throws Exception 例外
*/
private static void initServerInfos() throws Exception {
if (ServerInfosContainer.ipAddress == null) {
@@ -104,7 +104,7 @@ public class ServerInfoUtils {
/**
* 获取CPU序列号
*
- * @return String 主板序列号
+ * @return String CPU 序列号
*/
public static String getCpuSerial() {
return FileUtil.isWindows() ? getWindowCpuSerial() : getLinuxCpuSerial();
@@ -158,15 +158,22 @@ public class ServerInfoUtils {
*/
private static String getWindowCpuSerial() {
- String result = StrUtil.EMPTY;
+ StringBuilder result = new StringBuilder(StrUtil.EMPTY);
File file = null;
BufferedReader input = null;
try {
file = File.createTempFile("tmp", ".vbs");
file.deleteOnExit();
FileWriter fw = new FileWriter(file);
- String vbs = "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n" + "Set colItems = objWMIService.ExecQuery _ \n" + " (\"Select * from Win32_Processor\") \n" + "For Each objItem in colItems \n" + " Wscript.Echo objItem.ProcessorId \n" + " exit for ' do the first cpu only! \n" + "Next \n";
+ String vbs = """
+ Set objWMIService = GetObject("winmgmts:\\\\.\\root\\cimv2")
+ Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
+ For Each objItem In colItems
+ WScript.Echo objItem.ProcessorId
+ Exit For ' do the first cpu only!
+ Next
+ """;
fw.write(vbs);
fw.close();
@@ -174,7 +181,7 @@ public class ServerInfoUtils {
input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
- result += line;
+ result.append(line);
}
} catch (Exception e) {
log.error("获取window cpu信息错误, {}", e.getMessage());
@@ -182,7 +189,7 @@ public class ServerInfoUtils {
IoUtil.close(input);
FileUtil.del(file);
}
- return result.trim();
+ return result.toString().trim();
}
/**
@@ -191,23 +198,16 @@ public class ServerInfoUtils {
* @return {@link String}
*/
private static String getLinuxMainBoardSerial() {
- String result = StrUtil.EMPTY;
- String maniBordCmd = "dmidecode | grep 'Serial Number' | awk '{print $3}' | tail -1";
- BufferedReader br = null;
+ String command = "dmidecode | grep 'Serial Number' | awk '{print $3}' | tail -1";
try {
- Process p = Runtime.getRuntime().exec(new String[] {"sh", "-c", maniBordCmd});
- br = new BufferedReader(new InputStreamReader(p.getInputStream()));
- String line;
- while ((line = br.readLine()) != null) {
- result += line;
- break;
+ Process process = new ProcessBuilder("sh", "-c", command).start();
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
+ return reader.lines().findFirst().orElse(StrUtil.EMPTY);
}
} catch (IOException e) {
- log.error("获取Linux主板信息错误 {}", e.getMessage());
- } finally {
- IoUtil.close(br);
+ log.error("获取 Linux 主板序列号失败: {}", e.getMessage());
+ return StrUtil.EMPTY;
}
- return result;
}
/**
@@ -216,7 +216,7 @@ public class ServerInfoUtils {
* @return {@link String}
*/
private static String getWindowMainBoardSerial() {
- String result = StrUtil.EMPTY;
+ StringBuilder result = new StringBuilder(StrUtil.EMPTY);
File file = null;
BufferedReader input = null;
try {
@@ -224,7 +224,15 @@ public class ServerInfoUtils {
file.deleteOnExit();
FileWriter fw = new FileWriter(file);
- String vbs = "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n" + "Set colItems = objWMIService.ExecQuery _ \n" + " (\"Select * from Win32_BaseBoard\") \n" + "For Each objItem in colItems \n" + " Wscript.Echo objItem.SerialNumber \n" + " exit for ' do the first cpu only! \n" + "Next \n";
+ String vbs = """
+ Set objWMIService = GetObject("winmgmts:\\\\.\\root\\cimv2")
+ Set colItems = objWMIService.ExecQuery _
+ ("Select * from Win32_BaseBoard")
+ For Each objItem in colItems
+ Wscript.Echo objItem.SerialNumber
+ exit for ' do the first cpu only!
+ Next
+ """;
fw.write(vbs);
fw.close();
@@ -232,7 +240,7 @@ public class ServerInfoUtils {
input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
- result += line;
+ result.append(line);
}
} catch (Exception e) {
log.error("获取Window主板信息错误 {}", e.getMessage());
@@ -240,7 +248,7 @@ public class ServerInfoUtils {
IoUtil.close(input);
FileUtil.del(file);
}
- return result.trim();
+ return result.toString().trim();
}
/**
diff --git a/continew-starter-license/continew-starter-license-generate/README.md b/continew-starter-license/continew-starter-license-generate/README.md
index 922cf32f..f2c19670 100644
--- a/continew-starter-license/continew-starter-license-generate/README.md
+++ b/continew-starter-license/continew-starter-license-generate/README.md
@@ -36,8 +36,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import top.continew.license.dto.LicenseCreatorParamVO;
-import top.continew.license.dto.LicenseExtraModel;
+import top.continew.license.model.LicenseCreatorParamVO;
+import top.continew.license.model.LicenseExtraModel;
import top.continew.license.service.LicenseCreateService;
import java.util.Calendar;
diff --git a/continew-starter-license/continew-starter-license-generate/pom.xml b/continew-starter-license/continew-starter-license-generate/pom.xml
index e678f793..b7b7fa1e 100644
--- a/continew-starter-license/continew-starter-license-generate/pom.xml
+++ b/continew-starter-license/continew-starter-license-generate/pom.xml
@@ -11,25 +11,13 @@
- * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *
- * http://www.gnu.org/licenses/lgpl.html - *
- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package top.continew.license.dto; - -/** - * @Desc: - * @Author loach - * @ClassName top.continew.license.dto.ConfigParam - * @Date 2025-03-21 14:50 - */ -public class ConfigParam { - - /** 主题 */ - private String subject; - - /** 公钥别称 */ - private String publicAlias; - - /** 访问公钥库的密码 */ - private String storePass; - - public String getSubject() { - return subject; - } - - public void setSubject(String subject) { - this.subject = subject; - } - - public String getPublicAlias() { - return publicAlias; - } - - public void setPublicAlias(String publicAlias) { - this.publicAlias = publicAlias; - } - - public String getStorePass() { - return storePass; - } - - public void setStorePass(String storePass) { - this.storePass = storePass; - } -} diff --git a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/keyStoreParam/CustomKeyStoreParam.java b/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/keyStoreParam/CustomKeyStoreParam.java deleted file mode 100644 index b06325eb..00000000 --- a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/keyStoreParam/CustomKeyStoreParam.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. - *
- * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *
- * http://www.gnu.org/licenses/lgpl.html - *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package top.continew.license.keyStoreParam;
-
-import de.schlichtherle.license.AbstractKeyStoreParam;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * @Desc:
- * @Author loach
- * @ClassName top.continew.license.keyStoreParam.CustomKeyStoreParam
- * @Date 2025-03-21 14:50
- */
-public class CustomKeyStoreParam extends AbstractKeyStoreParam {
- /** 密钥路径,可为磁盘路径,也可为项目资源文件里的路径,如果为磁盘路径需重写getStream()方法 */
- private String storePath;
-
- /** 公钥或私钥的别名 */
- private String alias;
-
- /** 访问公钥/私钥库的密码 */
- private String storePass;
-
- /** 公钥/私钥的密码 */
- private String keyPass;
-
- public CustomKeyStoreParam(Class clazz, String resource, String alias, String storePass, String keyPass) {
- super(clazz, resource);
- this.storePath = resource;
- this.alias = alias;
- this.storePass = storePass;
- this.keyPass = keyPass;
- }
-
- @Override
- public String getAlias() {
- return alias;
- }
-
- @Override
- public String getStorePwd() {
- return storePass;
- }
-
- @Override
- public String getKeyPwd() {
- return keyPass;
- }
-
- @Override
- public InputStream getStream() throws IOException {
- return new FileInputStream(storePath);
- }
-}
diff --git a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/manager/ServerLicenseManager.java b/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/manager/ServerLicenseManager.java
index 47ff7e49..2f074e89 100644
--- a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/manager/ServerLicenseManager.java
+++ b/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/manager/ServerLicenseManager.java
@@ -18,16 +18,16 @@ package top.continew.license.manager;
import de.schlichtherle.license.*;
import de.schlichtherle.xml.GenericCertificate;
+import top.continew.license.exception.LicenseException;
import java.util.Date;
/**
* 自定义服务端证书管理类(生成证书)
*
- * @Desc:
- * @Author loach
- * @ClassName top.continew.license.manager.ServerLicenseManager
- * @Date 2025-03-22 14:31
+ * @author loach
+ * @author echo
+ * @since 2.11.0
*/
public class ServerLicenseManager extends LicenseManager {
@@ -38,27 +38,31 @@ public class ServerLicenseManager extends LicenseManager {
/**
* 证书生成参数验证
*
- * @param content
- * @throws LicenseContentException
+ * @param content 内容
*/
- protected synchronized void validateCreate(final LicenseContent content) throws LicenseContentException {
+ protected synchronized void validateCreate(final LicenseContent content) {
Date now = new Date();
Date notBefore = content.getNotBefore();
Date notAfter = content.getNotAfter();
if (notBefore != null && now.before(notBefore)) {
- throw new LicenseContentException("证书尚未生效,无法生成");
+ throw new LicenseException("证书尚未生效,无法生成");
}
if (notAfter != null && now.after(notAfter)) {
- throw new LicenseContentException("证书已过期,无法生成");
+ throw new LicenseException("证书已过期,无法生成");
}
if (notBefore != null && notAfter != null && notBefore.after(notAfter)) {
- throw new LicenseContentException("证书生效时间晚于失效时间,无法生成");
+ throw new LicenseException("证书生效时间晚于失效时间,无法生成");
}
}
/**
* 重写生成证书的方法,增加生成参数验证
+ *
+ * @param content 内容
+ * @param notary 公证人
+ * @return {@link byte[] }
+ * @throws Exception 例外
*/
@Override
protected synchronized byte[] create(LicenseContent content, LicenseNotary notary) throws Exception {
diff --git a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/service/LicenseCreateService.java b/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/service/LicenseCreateService.java
index ea84e622..ce798129 100644
--- a/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/service/LicenseCreateService.java
+++ b/continew-starter-license/continew-starter-license-generate/src/main/java/top/continew/license/service/LicenseCreateService.java
@@ -16,62 +16,51 @@
package top.continew.license.service;
+import cn.hutool.core.util.IdUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import de.schlichtherle.license.*;
+import net.lingala.zip4j.ZipFile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import top.continew.license.exception.LicenseException;
+import top.continew.license.manager.ServerLicenseManager;
+import top.continew.license.model.*;
+import top.continew.license.util.ExecCmdUtil;
+import top.continew.license.util.ServerInfoUtils;
+
+import javax.security.auth.x500.X500Principal;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.UUID;
import java.util.prefs.Preferences;
-import javax.security.auth.x500.X500Principal;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import de.schlichtherle.license.CipherParam;
-import de.schlichtherle.license.DefaultCipherParam;
-import de.schlichtherle.license.DefaultLicenseParam;
-import de.schlichtherle.license.KeyStoreParam;
-import de.schlichtherle.license.LicenseContent;
-import de.schlichtherle.license.LicenseManager;
-import de.schlichtherle.license.LicenseParam;
-import net.lingala.zip4j.ZipFile;
-import top.continew.license.dto.ConfigParam;
-import top.continew.license.dto.LicenseCreatorParam;
-import top.continew.license.dto.LicenseCreatorParamVO;
-import top.continew.license.dto.LicenseExtraModel;
-import top.continew.license.exception.LicenseException;
-import top.continew.license.keyStoreParam.CustomKeyStoreParam;
-import top.continew.license.manager.ServerLicenseManager;
-import top.continew.license.util.ExecCmdUtil;
-import top.continew.license.util.ServerInfoUtils;
-
/**
* 证书生成接口 实现类
*
- * @Desc:
- * @Author loach
- * @ClassName top.continew.license.service.impl.LicenseCreateServiceImpl
- * @Date 2025-03-22 18:36
- */
-@Component
+ * @author loach
+ * @since 2.11.0
+ **/
+
public class LicenseCreateService {
private static final Logger log = LoggerFactory.getLogger(LicenseCreateService.class);
private static volatile LicenseCreateService instance;
+ private static final X500Principal DEFAULT_HOLDER_ISSUER = new X500Principal("CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN");
+
private LicenseCreateService() {
- // 私有构造
}
+ /**
+ * 获取实例
+ *
+ * @return {@link LicenseCreateService }
+ */
public static LicenseCreateService getInstance() {
if (instance == null) {
synchronized (LicenseCreateService.class) {
@@ -83,135 +72,115 @@ public class LicenseCreateService {
return instance;
}
- private static final X500Principal DEFAULT_HOLDER_ISSUER = new X500Principal("CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN");
-
/**
* 获取服务器信息
*
- * @return
+ * @return {@link LicenseExtraModel }
*/
public LicenseExtraModel getServerInfo() {
- LicenseExtraModel serverInfos = ServerInfoUtils.getServerInfos();
- return serverInfos;
+ return ServerInfoUtils.getServerInfos();
}
/**
* 生成一个证书
*
- * @param paramVO
+ * @param paramVO param vo
+ * @throws Exception 例外
*/
public void generateLicense(LicenseCreatorParamVO paramVO) throws Exception {
- Map
- * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.gnu.org/licenses/lgpl.html
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package top.continew.license.dto;
-
-import java.util.Set;
-
-/**
- * 额外的服务器硬件校验信息对象,这里的属性可根据需求自定义
- *
- * @Desc:
- * @Author loach
- * @ClassName top.continew.license.dto.LicenseExtraModel
- * @Date 2025-03-21 14:28
- */
-public class LicenseExtraModel {
-
- /**
- * 可被允许的IP地址
- */
- private Set
- * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.gnu.org/licenses/lgpl.html
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package top.continew.license.exception;
-
-/**
- * 自定义校验异常
- *
- * @Desc:
- * @Author loach
- * @ClassName top.continew.license.exception.VerifyException
- * @Date 2025-04-11 14:58
- */
-public class VerifyException extends RuntimeException {
- public VerifyException(String message) {
- super(message);
- }
-
-}
diff --git a/continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/manager/CustomLicenseManager.java b/continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/manager/CustomLicenseManager.java
index e3905e7a..2ae67ba9 100644
--- a/continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/manager/CustomLicenseManager.java
+++ b/continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/manager/CustomLicenseManager.java
@@ -20,27 +20,30 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import de.schlichtherle.license.*;
import de.schlichtherle.xml.GenericCertificate;
import net.lingala.zip4j.ZipFile;
-import net.lingala.zip4j.exception.ZipException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-import top.continew.license.bean.LicenseInstallerBean;
import top.continew.license.autoconfigure.LicenseVerifyProperties;
-import top.continew.license.dto.ConfigParam;
-import top.continew.license.dto.LicenseExtraModel;
-import top.continew.license.keyStoreParam.CustomKeyStoreParam;
-import top.continew.license.utils.ServerInfoUtils;
+import top.continew.license.bean.LicenseInstallerBean;
+import top.continew.license.exception.LicenseException;
+import top.continew.license.model.ConfigParam;
+import top.continew.license.model.CustomKeyStoreParam;
+import top.continew.license.model.LicenseExtraModel;
+import top.continew.license.util.ServerInfoUtils;
-import java.io.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.prefs.Preferences;
/**
* 客户端证书管理类(证书验证)
*
* @author loach
- * @since 1.2.0
+ * @since 2.11.0
*/
-@Component
public class CustomLicenseManager extends LicenseManager {
private static final Logger log = LoggerFactory.getLogger(CustomLicenseManager.class);
@@ -48,7 +51,7 @@ public class CustomLicenseManager extends LicenseManager {
private static volatile CustomLicenseManager INSTANCE;
private LicenseExtraModel extraModel;
- private LicenseVerifyProperties properties;
+ private final LicenseVerifyProperties properties;
private CustomLicenseManager(LicenseVerifyProperties properties) {
this.properties = properties;
@@ -87,67 +90,49 @@ public class CustomLicenseManager extends LicenseManager {
/**
* 解压压缩包
- *
- * @throws ZipException
*/
private void extractZip() {
- ZipFile config = new ZipFile(properties.getStorePath() + File.separator + "clientLicense.zip");
- File licenseDir = new File(properties.getStorePath() + File.separator + "clientLicense");
- if (!licenseDir.exists()) {
- licenseDir.mkdir();
- }
- try {
- config.extractAll(licenseDir.getAbsolutePath());
- } catch (ZipException e) {
- log.error(e.getMessage());
- throw new RuntimeException(e);
+ Path zipPath = Paths.get(properties.getStorePath(), "clientLicense.zip");
+ Path outputDir = Paths.get(properties.getStorePath(), "clientLicense");
+
+ try (ZipFile zipFile = new ZipFile(zipPath.toFile())) {
+ if (!Files.exists(outputDir)) {
+ Files.createDirectories(outputDir);
+ }
+ zipFile.extractAll(outputDir.toAbsolutePath().toString());
+ } catch (IOException e) {
+ log.error("解压 clientLicense.zip 出错: {}", e.getMessage(), e);
+ throw new LicenseException("解压失败", e);
}
}
/**
* 获取压缩文件中配置的基础参数
*
- * @return
- * @throws Exception
+ * @return {@link ConfigParam }
*/
private ConfigParam getConfigParam() {
- FileInputStream config = null;
- BufferedReader reader = null;
- try {
- config = new FileInputStream(properties
- .getStorePath() + File.separator + "clientLicense/clientConfig.json");
- reader = new BufferedReader(new InputStreamReader(config, "UTF-8"));
- StringBuilder sb = new StringBuilder();
- String temp = null;
- while ((temp = reader.readLine()) != null) {
- sb.append(temp);
- }
- ObjectMapper mapper = new ObjectMapper();
- ConfigParam configParam = mapper.readValue(sb.toString(), ConfigParam.class);
- return configParam;
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (reader != null) {
- try {
- reader.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- if (config != null) {
- try {
- config.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
+ Path configPath = Paths.get(properties.getStorePath(), "clientLicense", "clientConfig.json");
+
+ if (!Files.exists(configPath)) {
+ log.warn("配置文件不存在: {}", configPath);
+ return null;
+ }
+
+ try (InputStream inputStream = Files.newInputStream(configPath)) {
+ ObjectMapper mapper = new ObjectMapper();
+ return mapper.readValue(inputStream, ConfigParam.class);
+ } catch (IOException e) {
+ log.error("读取配置文件失败: {}", e.getMessage(), e);
+ return null;
}
- return null;
}
/**
* 重写验证证书方法,添加自定义参数验证
+ *
+ * @param content 内容
+ * @throws LicenseContentException 许可证内容例外
*/
@Override
protected synchronized void validate(LicenseContent content) throws LicenseContentException {
@@ -155,27 +140,31 @@ public class CustomLicenseManager extends LicenseManager {
super.validate(content);
// 验证自定义参数
Object o = content.getExtra();
- if (o != null && extraModel != null && o instanceof LicenseExtraModel) {
- LicenseExtraModel contentExtraModel = (LicenseExtraModel)o;
+ if (extraModel != null && o instanceof LicenseExtraModel contentExtraModel) {
if (!contentExtraModel.getCpuSerial().equals(extraModel.getCpuSerial())) {
- throw new LicenseContentException("CPU核数不匹配");
+ throw new LicenseException("CPU核数不匹配");
}
if (!contentExtraModel.getMainBoardSerial().equals(extraModel.getMainBoardSerial())) {
- throw new LicenseContentException("主板序列号不匹配");
+ throw new LicenseException("主板序列号不匹配");
}
if (!contentExtraModel.getIpAddress().equals(extraModel.getIpAddress())) {
- throw new LicenseContentException("IP地址不匹配");
+ throw new LicenseException("IP地址不匹配");
}
if (!contentExtraModel.getMacAddress().equals(extraModel.getMacAddress())) {
- throw new LicenseContentException("MAC地址不匹配");
+ throw new LicenseException("MAC地址不匹配");
}
} else {
- throw new LicenseContentException("证书无效");
+ throw new LicenseException("证书无效");
}
}
/**
* 重写证书安装方法,主要是更改调用本类的验证方法
+ *
+ * @param key 钥匙
+ * @param notary 公证人
+ * @return {@link LicenseContent }
+ * @throws Exception 例外
*/
@Override
protected synchronized LicenseContent install(final byte[] key, LicenseNotary notary) throws Exception {
@@ -192,23 +181,31 @@ public class CustomLicenseManager extends LicenseManager {
/**
* 重写验证证书合法的方法,主要是更改调用本类的验证方法
+ *
+ * @param notary 公证人
+ * @return {@link LicenseContent }
+ * @throws Exception 例外
*/
@Override
protected synchronized LicenseContent verify(LicenseNotary notary) throws Exception {
GenericCertificate certificate = getCertificate();
- if (null != certificate)
+ if (certificate != null) {
return (LicenseContent)certificate.getContent();
-
- // Load license key from preferences,
- final byte[] key = getLicenseKey();
- if (null == key)
- throw new NoLicenseInstalledException(getLicenseParam().getSubject());
- certificate = getPrivacyGuard().key2cert(key);
+ }
+ byte[] licenseKey = getLicenseKey();
+ if (licenseKey == null) {
+ String subject = getLicenseParam().getSubject();
+ throw new NoLicenseInstalledException(subject);
+ }
+ // 使用私钥解密生成证书
+ certificate = getPrivacyGuard().key2cert(licenseKey);
+ // 验证证书签名
notary.verify(certificate);
- final LicenseContent content = (LicenseContent)certificate.getContent();
+ // 提取内容并进行业务校验
+ LicenseContent content = (LicenseContent)certificate.getContent();
this.validate(content);
+ // 缓存证书
setCertificate(certificate);
-
return content;
}
}
diff --git a/continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/utils/ServerInfoUtils.java b/continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/utils/ServerInfoUtils.java
deleted file mode 100644
index 7d499fe4..00000000
--- a/continew-starter-license/continew-starter-license-verify/src/main/java/top/continew/license/utils/ServerInfoUtils.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
- *
- * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.gnu.org/licenses/lgpl.html
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package top.continew.license.utils;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.StrUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import top.continew.license.dto.LicenseExtraModel;
-import top.continew.license.exception.VerifyException;
-
-import java.io.*;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * 服务器信息工具类
- *
- * @author Rong.Jia
- * @date 2022/03/10
- */
-public class ServerInfoUtils {
-
- private static final Logger log = LoggerFactory.getLogger(ServerInfoUtils.class);
-
- private static class ServerInfosContainer {
- private static Set 获取Mac地址 获取IP地址 获取某个网络地址对应的Mac地址 获取当前服务器所有符合条件的网络地址