fix(*) 首次提交LicenseAnalysis项目

This commit is contained in:
2023-08-23 16:37:50 +08:00
parent 3e05e32d4b
commit 4229247f77
16 changed files with 2335 additions and 0 deletions

88
LicenseAnalysis/pom.xml Normal file
View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.crtech.license_analysis</groupId>
<artifactId>LicenseAnalysis</artifactId>
<version>1.0.1</version>
<!-- 父工程 -->
<parent>
<groupId>cn.crtech.cloud.dependencies</groupId>
<artifactId>Dependencies</artifactId>
<version>1.0.1</version>
<relativePath/>
</parent>
<!-- 依赖的版本锁定 -->
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<oshi.version>5.8.3</oshi.version>
<fastjson.version>1.2.83</fastjson.version>
<jackson.version>1.9.13</jackson.version>
<dom4j.version>2.1.3</dom4j.version>
<common.version>1.0.1</common.version>
</properties>
<dependencies>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!-- 本机系统资源信息获取 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>${oshi.version}</version>
</dependency>
<!-- fast-json -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- jackson -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>${dom4j.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,105 @@
package cn.crtech.cloud.licenseAnalysis.api;
/**
* 统一返回实体
*
* @Author: TYP
* @Date: 2022-03-01 16:46
*/
public class Result {
private int code;
private String message;
private Object data;
private boolean success;
public Result() {
}
public Result(String message, boolean success) {
this.message = message;
this.success = success;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public static Result success() {
Result result = new Result();
result.setCode(ResultCode.SUCCESS.code());
result.setMessage(ResultCode.SUCCESS.message());
result.success = true;
return result;
}
public static Result success(Object data) {
Result result = Result.success();
result.setCode(ResultCode.SUCCESS.code());
result.setMessage(ResultCode.SUCCESS.message());
result.data = data;
return result;
}
public static Result success(Object data, String operation) {
Result result = Result.success();
result.data = data;
result.message = operation;
return result;
}
public static Result error() {
Result result = new Result();
result.success = false;
return result;
}
public static Result error(Object object) {
Result result = new Result();
result.success = false;
result.data = object;
return result;
}
public static Result error(ResultCode data) {
Result result = Result.error();
result.setCode(data.code());
result.setMessage(data.message());
return result;
}
public static Result error(Object data, String operation) {
Result result = Result.error();
result.data = data;
result.message = operation;
return result;
}
}

View File

@ -0,0 +1,118 @@
package cn.crtech.cloud.licenseAnalysis.api;
/**
* 统一返回体信息枚举
*
* @Author: TYP
* @Date: 2022-03-01 16:47
*/
public enum ResultCode {
/******************************** 系统通用 ************************************************/
SUCCESS(200, "success"),
SYSTEM_ERROR(10000, "系统异常"),
/******************************** 自定义异常 ************************************************/
EXIST_SAME_BUSINESS_LICENSE_COMPANY(10001, " 已存在相同营业执照号的公司"),
COMPANY_EXIST_MANAGER(10002, "当前企业已存在管理员用户"),
COMPANY_NOT_EXIST(10003, "参数异常,不存在当前公司"),
COMPANY_EXIST_SAME_ROE(10004, "公司已存在同名或同编号参数"),
COMPANY_EXIST_SAME_MOBILE_USER(10005, "本公司已存在该手机号绑定的员工"),
SYSTEM_EXIST_SAME_MOBILE_USER(10006, "系统已存在该手机号邦迪的用户"),
CURRENT_USER_NOT_EXIST(10007, "当前用户不存在"),
CURRENT_APPLICATION_GROUP_EXIST(10008, "请勿重复添加同名(同标识)产品分组"),
CURRENT_APPLICATION_GROUP_HAD_APPS(10009, "当前产品分组内存在产品数据,不可删除"),
CURRENT_APPLICATION_GROUP_EXIST_SAME_NAME_OR_CODE_APP(10010, "当前产品分组已存在同名或同标识产品,请勿重复添加"),
CURRENT_POPEDOM_OR_MENU_ALREADY_EXIST(10011, "已经存在同编号权限/菜单"),
CURRENT_POPEDOM_OR_MENU_HAD_CHILD_ITEM(10012, "不可删除!当前权限/菜单存在子数据"),
CURRENT_COMPANY_EXIST_SAME_CODE_APP(10013, "当前产品已存在授权版本,不允许重复添加或添加多个版本"),
CURRENT_COMPANY_ALREADY_EXIST_MANAGER_ROLE(10014, "当前公司已存在管理员角色,请勿重复添加!"),
CURRENT_COMPANY_NOT_EXIST_MANAGER_ROLE(10015, "当前公司暂不存在管理员角色,无法添加管理员账号!"),
LICENSE_DECODE_ERROR_PUBLIC_KEY(10016, "解码公钥为空"),
LICENSE_DECODE_ERROR_SIGN(10017, "签名为空"),
LICENSE_DECODE_ERROR_MACHINE_KEY(10018, "机器码为空"),
LICENSE_DECODE_ERROR_PRODUCT_SERIES_KEY(10019, "产品数据为空"),
LICENSE_DECODE_ERROR(10020, "license授权码解析异常"),
LICENSE_DECODE_ERROR_SIGN_ERROR(10021, "文件签名校验不一致"),
CURRENT_CLIENT_NOT_PUBLISH(10022, "当前客户端未建立授权信息,请联系商务"),
CURRENT_CLIENT_LICENSE_OVER_DUE(10023, "当前客户端授权信息已过期,请联系商务"),
CURRENT_CLIENT_LICENSE_NOT_AUTH(10024, "当前客户端未授权,请联系商务"),
CURRENT_CLIENT_LICENSE_DELETE(10025, "当前客户端授权信息已删除,请联系商务"),
REST_CONNECT_ERROR(10026, "客户端访问院端接口失败"),
SYSTEM_EXIST_SAME_NAME_OR_CODE_ROLE(10027, "系统已存在同名(同标识)角色,请勿重复添加"),
CURRENT_ROLE_BIND_USER(10028, "当前角色已经绑定用户,无法直接删除"),
CURRENT_MOBILE_ALREADY_EXIST(10029, "当前手机已绑定用户,不可重复添加"),
CURRENT_ACCOUNT_NOT_EXIST(10030, "用户未注册"),
CURRENT_INPUT_PASSWORD_ERROR(10031, "账号或密码输入错误"),
CURRENT_ACCOUNT_ALREADY_FROZEN(10032, "当前账号已被停用,请联系管理员进行处理"),
CURRENT_OLD_PASS_INPUT_ERROR(10033, "当前账号旧密码输入错误"),
CURRENT_SYSTEM_ALREADY_EXIST_SAME_NAME_OR_CODE_DICTIONARY_TYPE(10034, "系统已存在同名或者同标识的字典类型,无法重复添加/修改"),
CURRENT_SYSTEM_ALREADY_EXIST_SAME_NAME_OR_CODE_DICTIONARY_DATA(10035, "当前字典类型中已存在同名或者同标识的字典数据,无法重复添加/修改"),
EXIST_SAME_CODE_COMPANY(10036, " 已存在相同编码标识的公司"),
LICENSE_DOWNLOAD_FAIL(10037, "系统异常,授权文件下载失败"),
CR_FUNCTION_EXISTED(10038, "系统存在同名或同标识功能,请勿重复添加"),
MODIFY_PASSWORD_CHECK_ERROR(10038, "两次密码输入不一致"),
MODIFY_PASSWORD_SAME_PASS_ERROR(10039, "新密码与旧密码不可以相同"),
REGISTER_USER_EXIST_ERROR(10037, "用户已存在,无法注册"),
MODIFY_USERINFO_ERROR(10100, "没有用户信息被修改"),
/************************************* 授权 登录鉴权相关 ********************************************************/
SYSTEM_HAD_NOT_LICENSE(20000, "客户端未授权"),
SYSTEM_QUERY_PARAM_ERROR(20001, "请求参数异常"),
TOKEN_OVER_DUE(20002, "TOKEN已过期"),
USER_ALREADY_REMOTE_LOGIN(20003, "用户已在其他地方登录"),
USER_HAD_NOT_THIS_AUTH(20004, "当前用户没有此授权"),
USER_ALREADY_LOGOUT(20005, "用户已登出"),
SYSTEM_APPLICATION_AUTH_OVER(20006,"授权产品已过期"),
SYSTEM_APPLICATION_HAD_NOT_AUTH(20007,"当前系统未授权PIVAS云·药品知识库·院端产品"),
;
private int code;
private String message;
ResultCode(int code, String message) {
this.code = code;
this.message = message;
}
public void setCode(int code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
public int code() {
return this.code;
}
public String message() {
return this.message;
}
@Override
public String toString() {
return super.toString();
}
}

View File

@ -0,0 +1,109 @@
package cn.crtech.cloud.licenseAnalysis.launcher;
import cn.crtech.cloud.licenseAnalysis.pojo.License;
import cn.crtech.cloud.licenseAnalysis.utils.AESUtil;
import cn.crtech.cloud.licenseAnalysis.utils.MD5;
import cn.crtech.cloud.licenseAnalysis.utils.StaticResource;
import cn.crtech.cloud.licenseAnalysis.utils.SystemLogger;
import java.io.*;
/**
* desc
*
* @author: TYP
* @date: 2022-12-28 15:27
*/
public class CompanyValid {
// 是否已经设置CompanyCode
private static boolean hadCompanyCode = false;
private static SystemLogger logger = new SystemLogger(CompanyValid.class);
public static void valid() {
if (License.getLicense().getCompanyCode() == null) {
boolean read = readCompanyInfo();
if (!read) {
logger.info("系统暂未配置授权公司秘钥,允许客户自行进行配置!");
} else {
setHad(true);
}
} else {
setHad(true);
}
}
private static String generateKey() throws IOException {
String key = "Crtech2021";
return MD5.md5(key.getBytes("UTF-8"));
}
public static void createCompanyInfo(String companyCode) {
FileWriter fw = null;
try {
File file = new File(StaticResource.FILE_PATH + "/company");
if (file.exists()) {
file.delete();
}
String key = generateKey();
String cipher = AESUtil.encrypt(companyCode, key);
fw = new FileWriter(StaticResource.FILE_PATH + "/company");
fw.write(cipher);
License.setCompanyCode(companyCode);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static boolean readCompanyInfo() {
File file = new File(StaticResource.FILE_PATH + "/company");
if (file.exists()) {
InputStreamReader is = null;
BufferedReader br = null;
try {
is = new InputStreamReader(new FileInputStream(file), "UTF-8");
br = new BufferedReader(is);
String lineTxt = null;
StringBuffer str = new StringBuffer();
while ((lineTxt = br.readLine()) != null) {
str.append(lineTxt);
}
String key = generateKey();
String decrypt = AESUtil.decrypt(str.toString(), key);
License.setCompanyCode(decrypt);
return true;
} catch (Exception e) {
e.printStackTrace();
logger.error("解析Company配置信息异常:" + e.getMessage());
}
}
return false;
}
public static void setHad(boolean set) {
hadCompanyCode = set;
}
public static boolean getHad() {
return hadCompanyCode;
}
public static void delCompanyInfo() {
File file = new File(StaticResource.FILE_PATH + "/company");
if (file.exists()) {
file.delete();
}
setHad(false);
License.setCompanyCode(null);
}
}

View File

@ -0,0 +1,345 @@
package cn.crtech.cloud.licenseAnalysis.launcher;
import cn.crtech.cloud.licenseAnalysis.utils.AESUtil;
import cn.crtech.cloud.licenseAnalysis.utils.MD5;
import cn.crtech.cloud.licenseAnalysis.utils.MachineInfo;
import cn.crtech.cloud.licenseAnalysis.utils.StaticResource;
import cn.crtech.cloud.licenseAnalysis.utils.SystemLogger;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.ObjectUtils;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 授权码校验
*
* @author inaisen
*/
public class LauncherValid {
private static final SystemLogger logger = new SystemLogger(LauncherValid.class);
/**
* 主板序列号
*/
private static String BaseBoradSN;
/**
* CPU序列号
*/
private static String CpuSN;
/**
* 硬盘S/N
*/
private static String DiskSN;
/**
* 授权唯一UUID
*/
public static String UD;
/**
* 授权文件物理地址
*/
private static File cipherFile = new File(StaticResource.FILE_PATH, StaticResource.CHIPER_FILE);
public static File licenseFile = new File(StaticResource.FILE_PATH, "license");
private static String cipherContent;
/**
* 初始化服务器(电脑)运行环境信息
*/
public static void init() {
BaseBoradSN = MachineInfo.getSerialnumber();
CpuSN = MachineInfo.getprocessorid();
DiskSN = MachineInfo.getDisksNumber();
}
/**
* 验证授权码文件,有误则删除重新生成
*
* @throws Exception 异常信息
*/
public static void valid() throws Exception {
boolean f = false;
logger.info("开始验证授权码文件 =============> ");
try {
f = validCipher();
logger.info("授权码文件校验结果 ==> {} ", f);
} catch (Exception e) {
logger.error("验证授权码文件异常 ==> {} ", e.getMessage());
}
if (!f) {
logger.info("验证授权码文件失败 重新生成");
generateCipher();
}
}
/**
* 获取机器码数据
*
* @return 返回数据
*/
public static String getCode() {
return cipherContent;
}
/**
* 校验机械码数据是否正确
*
* @param licenseContent 机械码
* @return 返回判断结果
* @throws IOException 信息读取异常
*/
public static boolean validLicenseCipher(String licenseContent) throws IOException {
String key = generateKey();
return validCipher(AESUtil.decrypt(licenseContent, key));
}
/**
* 解密授权码,验证系统信息
*
* @return 处理结果
* @throws IOException 文件读取异常
*/
private static boolean validCipher() throws Exception {
String key = generateKey();
String cipher = loadCipher();
String content = AESUtil.decrypt(cipher, key);
if (validCipher(content)) {
cipherContent = cipher;
return true;
} else {
if (checkMachineFile(content, null, null, true)) {
cipherContent = cipher;
return true;
}
return false;
}
}
/**
* 校验机械码内容
*
* @param content 内容
* @return 返回判断结果
* @throws IOException 数据读取异常
*/
private static boolean validCipher(String content) throws IOException {
if (!ObjectUtils.isEmpty(content)) {
init();
Map<String, Object> cipherMap = JSON.parseObject(content, Map.class);
if (!BaseBoradSN.equals(cipherMap.get("bs"))) {
logger.error("签名校验异常(BS) ==> 继续校验是否由于编码BOM导致错误 ====> ");
String bs = deleteUTF8Bom(cipherMap.get("bs").toString());
if (!BaseBoradSN.equals(bs)) {
logger.error("签名校验异常(BS) ==> 本机(" + BaseBoradSN + ") != 解析数据(" + cipherMap.get("bs") + ")");
return false;
}
logger.info("====> 签名校验异常(BS) 是由于文件编码BOM导致异常 现已进行处理 结果允许通过");
}
if (!CpuSN.equals(cipherMap.get("cs"))) {
logger.error("签名校验异常(CS) ==> 继续校验是否由于编码BOM导致错误 ====> ");
String cs = deleteUTF8Bom(cipherMap.get("cs").toString());
if (!CpuSN.equals(cs)) {
logger.error("签名校验异常(CS) ==> 本机(" + CpuSN + ") != 解析数据(" + cipherMap.get("cs") + ")");
return false;
}
logger.info("====> 签名校验异常(CS) 是由于文件编码BOM导致异常 现已进行处理 结果允许通过");
}
if (!DiskSN.equals(cipherMap.get("ds"))) {
logger.error("签名校验异常(DS) ==> 继续校验是否由于编码BOM导致错误 ====> ");
String ds = deleteUTF8Bom(cipherMap.get("ds").toString());
if (!DiskSN.equals(ds)) {
logger.error("签名校验异常(DS) ==> 本机(" + DiskSN + ") != 解析数据(" + cipherMap.get("ds") + ")");
return false;
}
logger.info("====> 签名校验异常(DS) 是由于文件编码BOM导致异常 现已进行处理 结果允许通过");
}
if (!StaticResource.RUN_PATH.equals(cipherMap.get("rp"))) {
logger.error("签名校验异常(RUN_PATH) ==> 继续校验是否由于编码BOM导致错误 ====> ");
String rp = deleteUTF8Bom(cipherMap.get("rp").toString());
if (!StaticResource.RUN_PATH.equals(rp)) {
logger.error("签名校验异常(RUN_PATH) ==> 本机(" + StaticResource.RUN_PATH + ") != 解析数据(" + cipherMap.get("rp") + ")");
return false;
}
logger.info("====> 签名校验异常(RUN_PATH) 是由于文件编码BOM导致异常 现已进行处理 结果允许通过");
}
long mt = cipherFile.lastModified();
long ct = Long.parseLong(cipherMap.get("ct").toString());
if (Math.abs(ct - mt) <= 1000) {
UD = cipherMap.get("ud").toString();
return true;
}
logger.error("签名校验异常(文件时间异常) ==> Math.abs(ct" + ct + " - mt" + mt + ") > 1000");
}
return false;
}
private static String deleteUTF8Bom(String fileStr) {
byte[] UTF8_BOM_BYTES = new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
byte[] bytes = fileStr.getBytes();
if (bytes[0] == UTF8_BOM_BYTES[0]
&& bytes[1] == UTF8_BOM_BYTES[1]
&& bytes[2] == UTF8_BOM_BYTES[2]) {
return new String(bytes, 3, bytes.length - 3);
}
return fileStr;
}
/**
* 读取授权码文件
*
* @return 返回处理结果
* @throws IOException 异常
*/
public static String loadCipher() throws IOException {
FileInputStream fis = null;
try {
if (!cipherFile.exists()) {
cipherFile.createNewFile();
}
fis = new FileInputStream(cipherFile);
int iAvail = fis.available();
byte[] bytes = new byte[iAvail];
fis.read(bytes);
return new String(bytes, "UTF-8");
} catch (IOException e) {
throw e;
} finally {
if (fis != null) {
fis.close();
}
}
}
/**
* 加密授权码写入授权文件
*
* @throws IOException 异常
*/
private static void generateCipher() throws IOException {
String key = generateKey();
String content = generateCipherContent();
String cipher = AESUtil.encrypt(content, key);
if (cipherFile.exists()) {
cipherFile.delete();
} else {
if (licenseFile.exists()) {
licenseFile.delete();
}
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(cipherFile);
fos.write(cipher.getBytes("UTF-8"));
fos.flush();
cipherContent = cipher;
} catch (FileNotFoundException e) {
e.printStackTrace();
File confFile = new File(StaticResource.FILE_PATH);
if (!confFile.exists()) {
confFile.mkdir();
generateCipher();
}
} finally {
if (fos != null) {
fos.close();
}
}
}
/**
* 获得本机授权文件密钥
*
* @return 返回生成结果
* @throws IOException 异常
*/
public static String generateKey() throws IOException {
String key = "Crtech2021";
return MD5.md5(key.toString().getBytes("UTF-8"));
}
/**
* 获得本机物理地址信息返回待加密的JSON
*
* @return 返回处理结果
*/
private static String generateCipherContent() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("bs", MachineInfo.getSerialnumber());
map.put("cs", MachineInfo.getprocessorid());
map.put("ds", MachineInfo.getDisksNumber());
map.put("rp", StaticResource.RUN_PATH);
UD = UUID.randomUUID().toString();
map.put("ud", UD);
map.put("ct", System.currentTimeMillis());
return JSON.toJSONString(map);
}
/**
* 机器码数据信息解析
*
* @param machineInfoKey 机械码
* @return 返回解析内容
* @throws Exception 异常
*/
public static Map<String, Object> decodeMachineInfoKey(String machineInfoKey) throws Exception {
String key = generateKey();
String cipher = AESUtil.decrypt(machineInfoKey, key);
Map<String, Object> cipherMap = JSON.parseObject(cipher, Map.class);
return cipherMap;
}
/**
* 授权码文件数据校验
*
* @param systemInfo 系统信息
* @param machineInfoKey 机械码
* @param prod 是否正式校验 false时表示测试
* @return 返回判断结果
* @throws Exception 异常
*/
public static boolean checkMachineFile(String contentInfo, String systemInfo, String machineInfoKey, boolean prod) throws Exception {
if (machineInfoKey == null || "".equals(machineInfoKey)) {
machineInfoKey = LauncherValid.loadCipher();
}
Map<String, Object> machineInfoMap = decodeMachineInfoKey(machineInfoKey);
if (contentInfo == null || "".equals(contentInfo)) {
String key = generateKey();
contentInfo = AESUtil.decrypt(systemInfo, key);
}
if (!ObjectUtils.isEmpty(contentInfo) || !ObjectUtils.isEmpty(machineInfoMap)) {
Map<String, Object> cipherMap = JSON.parseObject(contentInfo, Map.class);
if (prod) {
return (machineInfoMap.get("bs").toString().equals(cipherMap.get("bs"))
&& machineInfoMap.get("cs").toString().equals(cipherMap.get("cs"))
&& machineInfoMap.get("ds").toString().equals(cipherMap.get("ds"))
&& StaticResource.RUN_PATH.equals(cipherMap.get("rp")));
} else {
return (machineInfoMap.get("bs").toString().equals(cipherMap.get("bs"))
&& machineInfoMap.get("cs").toString().equals(cipherMap.get("cs"))
&& machineInfoMap.get("ds").toString().equals(cipherMap.get("ds"))
&& machineInfoMap.get("rp").toString().equals(cipherMap.get("rp")));
}
}
return false;
}
}

View File

@ -0,0 +1,303 @@
package cn.crtech.cloud.licenseAnalysis.launcher;
import cn.crtech.cloud.licenseAnalysis.utils.AESUtil;
import cn.crtech.cloud.licenseAnalysis.utils.Sha1WithRsaUtil;
import cn.crtech.cloud.licenseAnalysis.pojo.Application;
import cn.crtech.cloud.licenseAnalysis.pojo.License;
import cn.crtech.cloud.licenseAnalysis.utils.StaticResource;
import cn.crtech.cloud.licenseAnalysis.utils.SystemLogger;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 授权信息校验/初始化/处理工具类
*/
public class LicenseValid {
public static File licenseFile = new File(StaticResource.FILE_PATH, "license");
private static SystemLogger logger = new SystemLogger(LicenseValid.class);
public static void valid() {
try {
// 判断文件是否存在
if (!licenseFile.isFile() || !licenseFile.exists()) {
logger.error("文件不存在");
throw new Exception("文件不存在");
}
readLicense(new FileInputStream(licenseFile));
} catch (Exception e) {
writeError("载入授权文件[" + licenseFile.getAbsolutePath() + "]失败: " + e.getMessage());
}
}
/**
* 重写 license文件 方便读取自己传入的文件
*
* @param file 文件
*/
protected static void validByPersonalFile(File file) {
try {
// 判断文件是否存在
if (!file.isFile() || !file.exists()) {
throw new Exception("文件不存在");
}
readLicense(new FileInputStream(file));
} catch (Exception e) {
writeError("载入授权文件[" + file.getAbsolutePath() + "]失败: " + e.getMessage());
}
}
/**
* 重写 根据传入的文件地址 读取license数据
*
* @param filePath 文件地址
*/
protected static void validByFilePath(String filePath) {
File file = new File(filePath);
validByPersonalFile(file);
}
/**
* 读取license文件返回publicKey,授权Json串,企业信息
*/
public static void readLicense(InputStream is) throws Exception {
String encoding = "UTF-8";
// 考虑到编码格式
InputStreamReader read = null;
try {
read = new InputStreamReader(is, encoding);
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt = null;
List<String> str = new ArrayList<>();
int i = 0;
while ((lineTxt = bufferedReader.readLine()) != null) {
str.add(lineTxt);
i++;
}
//license中文本信息小于4行则表示license文件有有误
if (i != 4) {
logger.error("文本信息小于4行license文件有有误");
throw new Exception("文本信息小于4行license文件有有误");
}
String privateEncrypt = str.get(0);
String publicKey = str.get(1);
String application = str.get(2);
String sign = str.get(3);
String systemInfo = Sha1WithRsaUtil.decrypt(privateEncrypt, Sha1WithRsaUtil.getPublicKeyX509(publicKey));
if (!LauncherValid.validLicenseCipher(systemInfo)) {
logger.error("validLicenseCipher ===> 系统签名认证错误");
if (!LauncherValid.checkMachineFile(null, systemInfo, null, true)) {
logger.error("checkMachineFile ===> 系统签名认证错误");
throw new Exception("checkMachineFile ===> 系统签名认证错误");
} else {
logger.info("checkMachineFile ===> 系统签名认证通过");
}
}
String json = AESUtil.decrypt(application, systemInfo);
// 验证签名
if (!Sha1WithRsaUtil.verify(json, sign, publicKey)) {
logger.error("公有签名认证错误");
throw new Exception("公有签名认证错误");
}
write(json);
} finally {
if (read != null) {
read.close();
}
}
}
/**
* 读取license文件返回publicKey,授权Json串,企业信息
*/
public static void initLicenseFile(List<String> info) {
try {
String privateEncrypt = info.get(0);
String publicKey = info.get(1);
String application = info.get(2);
String sign = info.get(3);
String systemInfo = Sha1WithRsaUtil.decrypt(privateEncrypt, Sha1WithRsaUtil.getPublicKeyX509(publicKey));
if (!LauncherValid.validLicenseCipher(systemInfo)) {
logger.error("validLicenseCipher ===> 系统签名认证错误");
if (!LauncherValid.checkMachineFile(null, systemInfo, null, true)) {
logger.error("checkMachineFile ===> 系统签名认证错误");
throw new Exception("checkMachineFile ===> 系统签名认证错误");
} else {
logger.info("checkMachineFile ===> 系统签名认证通过");
}
}
String json = AESUtil.decrypt(application, systemInfo);
// 验证签名
if (!Sha1WithRsaUtil.verify(json, sign, publicKey)) {
logger.error("公有签名认证错误");
throw new Exception("公有签名认证错误");
}
createLicense(info);
write(json);
} catch (Exception e) {
}
}
/**
* 授权文件信息写入
* @param info 信息
*/
private static void createLicense(List<String> info) {
FileWriter fw = null;
try {
File file = new File(StaticResource.FILE_PATH + "/license");
if (file.exists()) {
file.delete();
}
fw = new FileWriter(StaticResource.FILE_PATH + "/license");
StringBuffer key = new StringBuffer();
for (int i = 0; i <= (info.size() - 1); i++) {
key.append(info.get(i));
if (i != (info.size() - 1)) {
key.append("\n");
}
}
fw.write(key.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 删除授权文件
* @return 返回处理结果
*/
public static boolean deleteLicense() {
File file = new File(StaticResource.FILE_PATH, "license");
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) {
if (file.delete()) {
return true;
} else {
return false;
}
} else {
return false;
}
}
/**
* 输出调用处理错误
* @param errorMessage 错误信息
*/
public static void writeError(String errorMessage) {
License.validLicense = false;
License.error = errorMessage;
logger.error(errorMessage);
deleteLicense();
}
/**
* 授权信息写入
* @param licenseJSON 授权信息
*/
public static void write(String licenseJSON) {
License.init(licenseJSON);
logger.info("license文件内容初始化完成");
}
/**
* 校验系统授权是否含有对应产品
*
* @param appCode 产品标识
* @return 返回判断结果
*/
public static boolean checkApplication(String appCode) {
if (License.validLicense) {
List<Application> appList = License.getLicense().getApplications();
for (Application app : appList) {
if (app.getCode().equals(appCode)) {
if (app.getExpiryTime() > new Date().getTime()) {
return false;
} else {
logger.error("产品[" + app.getName() + "]授权已过期,系统无法访问!");
return true;
}
}
}
}
return false;
}
/**
* 获取客户端授权产品信息
* @param appCode 产品标识
* @return 返回查询结果
*/
public static Application getClientApplication(String appCode) {
if (License.validLicense) {
List<Application> appList = License.getLicense().getApplications();
for (Application app : appList) {
if (app.getCode().equals(appCode)) {
return app;
}
}
}
logger.error("当前产品不存在或者未授权");
return null;
}
/**
* 自定义测试处理方法
*/
public static void main(String[] args) {
String machineInfoKey = "cNSGlMwZy8GxLDTo3QxuAXsNj5XIaZYCCl3hEeO0wOrWA7qktwfFETgVUiLxgG5vCmP/9CW0siRwgKkPcAf++/0JUmzjGnEftmMb+D226GCpPjvQbAUFX7Hin+ycEfN2IkL6F6FchZLtdZoJOAbAn7RRv+eZB5hd2r9/TQr1IiEGYpQc5MX4mIGX4xFkt3G0RZrIRp0PK/2YHxaMvb7QPepzfsrwbs6XXQ6BrL/7m4xreW8JAt8nhjjCuaDSCkOU";
String licenseInfoKey = "ctn0H_0CZl2Y2R3XoCF_b41PGRjdyiejgd9XtdduI6FkHwTeMOFcxvFL-B5yd7fhj6HY7sEVuSP1yejcheavfDImEbvlzFrR44ZG1Ab-3KRQ6MT95i9pGV_hEgd22T61u4oNyoQg8hBaucT4mvZrML3JZLf4funvtj7cJi1Mp0nInL61p3oevq2Of8hhrLBpW9jUcWSZG07N4m5Fy4sBwCG6HmmF_WFABXPJ6R2LwhHqT8GG7aOqctVLK4lQddpf-iu0U8GHdqXxpDJpYJCo3Bxj148aJlYzrPOPbOcO6VC-LvlT_xt4rikXk-STHIDNeI9s9y6_UsXPn3xx1CJOQyqg3PPahf2uZENh_9FMNpqII7Mzs1vg5wnnVE3bnO4a9Ga-q06lu3QKdglK4f_RAzuJYFIm6HjLUhXFCwuTH7-RrUdFmiaQw48BlmZ3Htj9zb1RherKxKjQ4rJgF6b2HYI58tBeEnwz70RTO87MGU9RyHIL0UD89qwNIuH3-n3tnh-V5xT9gCld3VITRJ2Yi46O12WKQ6TW1zNEaVd3FrVypzS1P4FLOkmXsoePUUy4PZ2uZo6oSClQVndr76pmb1dg7Z9reaqXfG5OJsNGk7B9Fr6fm16HZYyzpipo_0_49aJu39Gqm9_i-sb0JUmTGgUEmQj_1kTfNp_XL7SE1lk\n" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAorYr1WMkcu9GqEtRAqIvEjoO-8PUIfzJ__icQifSYf51q7-i98H3YfdBtHddr1G8QAxgh6V8I7ejznbpcZUQy8ZRJiSCtd6gPkQiDoP3tZzfv58mHsnb6GHo4UDFTkjHlIwBBY7gMRlH4oitlpwvqbpyQPMal19zP8AkbmjrS_RYr4d-xJbyRpAh80N6VZ255TdsxBWu8KznvK3rqklUuCOfzcFmW71UETHYLd1m_46anWrjtN-2Yj5XPx3OhewyNcBJnjgOxNQxEIyAdxDLKaI-lhzMQl_hx5hMRHsGNvqGQnutE3h7wJKoiyRZPz1y_i7wpNoVaGnRKHSuvEK66QIDAQAB\n" +
"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\n" +
"Duzcuty33a7-g2Nphj5zhv5uJDZ-ZFkPx4Huqrp_38m1NYfgc8fShq2YE8CpODH9XsHLi3Ve2U02SQQRluPywRbRrNFtjqQxXcHU9uCUP8BaJtX-0SYdzXNWZcP5tQRfRvqhpIIpTn69keHJHqBybL4Zs9h0-0GMR2ejPEKSkInDWD5LieGyh8KnVr42HErg4d-WKQIbhopYjXAGBKOdcHoWC0L11AZxPULSGaVyvX9nGtKAerYsB-eLSWzWF3SSDSw2fI6qTsMAKwCZDunw48bPLBKc9ubU2ibayzzTanMk1EMb1PqOoHKpoOmTiThktfKlEjAdApXtE0cQXod-4w";
try {
String[] str = licenseInfoKey.split("\\\n");
String privateEncrypt = str[0];
String publicKey = str[1];
String application = str[2];
String sign = str[3];
String systemInfo = Sha1WithRsaUtil.decrypt(privateEncrypt, Sha1WithRsaUtil.getPublicKeyX509(publicKey));
if (!LauncherValid.validLicenseCipher(systemInfo)) {
logger.error("validLicenseCipher ===> 系统签名认证错误");
boolean checkMachineFile = LauncherValid.checkMachineFile(null, systemInfo, machineInfoKey, false);
if (!checkMachineFile) {
logger.error("checkMachineFile ===> 系统签名认证错误");
throw new Exception("checkMachineFile ===> 系统签名认证错误");
} else {
logger.info("checkMachineFile ===> 系统签名认证通过");
}
}
String json = AESUtil.decrypt(application, systemInfo);
// 验证签名
if (!Sha1WithRsaUtil.verify(json, sign, publicKey)) {
throw new Exception("共有签名认证错误");
}
write(json);
License license = License.getLicense();
System.out.println(license.toString());
} catch (Exception e) {
e.fillInStackTrace();
}
}
}

View File

@ -0,0 +1,154 @@
package cn.crtech.cloud.licenseAnalysis.launcher;
import cn.crtech.cloud.licenseAnalysis.utils.SystemLogger;
import lombok.extern.slf4j.Slf4j;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
/**
* License授权 系统启动工具类
*
* @Author: TYP
* @Date: 2021-09-13 15:53
*/
@Slf4j
public class SystemInit {
//项目配置文件存储文件夹路径
public static final String FILE_PATH = System.getProperty("user.dir") + File.separator + "src" +
File.separator + "main" + File.separator + "resources" + File.separator + "conf";
private static SystemLogger logger = new SystemLogger(SystemInit.class);
/**
* 系统初始化
*/
public static void init() {
// 判断对应文件夹是否存在 不存在就自动创建
File file = new File(FILE_PATH);
if (!file.exists()) {
file.mkdirs();
}
log.info("================ 初始化读取电脑系统配置信息 ================");
try {
LauncherValid.valid();
} catch (Exception e) {
log.debug("初始化读取电脑系统配置信息失败 电脑配置文件重置完成");
}
log.info("================ 初始化系统License文件 ================");
try {
LicenseValid.valid();
} catch (Exception e) {
log.debug("初始化读取系统License文件失败");
}
log.info("================ 初始化系统公司配置数据 ================");
try {
CompanyValid.valid();
} catch (Exception e) {
log.debug("初始化读取系统公司配置数据失败");
}
}
/**
* 上传授权文件
*
* @param file 文件
*/
public static void uploadLicenseFile(File file) {
FileReader reader = null;
BufferedReader br = null;
try {
reader = new FileReader(file);
br = new BufferedReader(reader);
List<String> keys = new ArrayList<>();
String line = "";
int i = 0;
while ((line = br.readLine()) != null) {
keys.add(line);
i++;
}
if (i != 4) {
logger.error("文本信息小于4行license文件有有误");
throw new Exception("文本信息小于4行license文件有有误");
}
CompanyValid.delCompanyInfo();
LicenseValid.initLicenseFile(keys);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
if (reader != null) {
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 上传授权文件
*
* @param filePath 文件地址
*/
public static void uploadLicenseFile(String filePath) {
FileReader reader = null;
BufferedReader br = null;
try {
reader = new FileReader(filePath);
;
br = new BufferedReader(reader);
List<String> keys = new ArrayList<>();
String line = "";
int i = 0;
while ((line = br.readLine()) != null) {
keys.add(line);
i++;
}
if (i != 4) {
logger.error("文本信息小于4行license文件有有误");
throw new Exception("文本信息小于4行license文件有有误");
}
CompanyValid.delCompanyInfo();
LicenseValid.initLicenseFile(keys);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
if (reader != null) {
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 设置企业自定义标识内容
*
* @param companyCode 企业标识
*/
public static void setCompanyCode(String companyCode) {
if (!CompanyValid.getHad()) {
CompanyValid.createCompanyInfo(companyCode);
} else {
logger.error("系统已有相关配置!不可重复配置!");
}
}
}

View File

@ -0,0 +1,77 @@
package cn.crtech.cloud.licenseAnalysis.pojo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Application {
@Override
protected Application clone() {
Application tmp = new Application();
tmp.code = this.code;
tmp.name = this.name;
tmp.version = this.version;
tmp.expiryTime = this.expiryTime;
tmp.grade = this.grade;
tmp.gradeName = this.gradeName;
tmp.popedoms = new ArrayList<>();
for (Map<String, String> popedom : this.popedoms) {
Map<String, String> p = new HashMap<>();
p.putAll(popedom);
tmp.popedoms.add(p);
}
tmp.params = new HashMap<>();
for (Param param : this.params.values()) {
Param p = param.clone();
tmp.params.put(p.code, p);
}
return tmp;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
public String getVersion() {
return version;
}
public long getExpiryTime() {
return expiryTime;
}
public String getGrade() {
return grade;
}
public String getGradeName() {
return gradeName;
}
public List<Map<String, String>> getPopedoms() {
return popedoms;
}
public Map<String, Param> getParams() {
return params;
}
public Param getParam(String code) {
return params.get(code);
}
protected String code;
protected String name;
protected String version;
protected long expiryTime;
protected String grade;
protected String gradeName;
protected List<Map<String, String>> popedoms;
protected Map<String, Param> params;
}

View File

@ -0,0 +1,141 @@
package cn.crtech.cloud.licenseAnalysis.pojo;
import cn.crtech.cloud.licenseAnalysis.launcher.CompanyValid;
import cn.crtech.cloud.licenseAnalysis.utils.StaticResource;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class License {
public static boolean validLicense = false;
public static String error;
private String applicationGroup;
private List<Application> applications;
private Map<String, String> company;
private boolean dev;
private String secret;
private String auth_code;
private String company_code;
private static License license = new License();
public static License getLicense() {
return license.clone();
}
public static void init(String licenseJSON) {
Gson gson = new Gson();
Map<String, Object> lm = gson.fromJson(licenseJSON,Map.class);
License.validLicense = true;
License.error = null;
License.license.applicationGroup = (String) lm.get("application_group");
License.license.company = (Map<String, String>) lm.get("company");
License.license.applications = new ArrayList<>();
License.license.secret = (String) lm.get("secret");
License.license.auth_code = (String) lm.get("auth_code");
if (lm.get("company_code") == null) {
CompanyValid.setHad(false);
} else {
License.license.company_code = (String) lm.get("company_code");
CompanyValid.setHad(true);
}
List<Map<String, Object>> apps = (List<Map<String, Object>>) lm.get("applications");
Application a;
Param p;
for (Map<String, Object> app : apps) {
a = new Application();
a.code = (String) app.get("application_code");
a.name = (String) app.get("name");
a.version = (String) app.get("version");
a.expiryTime = (long) app.get("expiryTime");
a.grade = (String) app.get("grade");
a.gradeName = (String) app.get("gradeName");
a.popedoms = (List<Map<String, String>>) app.get("popedoms");
a.params = new HashMap<String, Param>();
List<Map<String, Object>> params = (List<Map<String, Object>>) app.get("params");
for (Map<String, Object> param : params) {
p = new Param();
p.code = (String) param.get("code");
p.name = (String) param.get("name");
p.value = param.get("value") + "";
p.valueType = param.get("valueType").toString();
p.falseDefault = param.get("falseDefault") == null ? "" : param.get("falseDefault").toString();
p.trueDefault = param.get("trueDefault") == null ? "" : param.get("trueDefault").toString();
p.description = (String) param.get("description");
a.params.put(p.code, p);
}
License.license.applications.add(a);
}
}
@Override
protected License clone() {
License tmp = new License();
tmp.applicationGroup = this.applicationGroup;
tmp.applications = new ArrayList<>();
for (Application application : this.applications) {
tmp.applications.add(application.clone());
}
tmp.company = new HashMap<>();
tmp.dev = StaticResource.isDev();
tmp.company.putAll(this.company);
tmp.secret = this.secret;
tmp.auth_code = this.auth_code;
tmp.company_code = this.company_code;
return tmp;
}
public boolean isDev() {
return dev;
}
public String getApplicationGroup() {
return applicationGroup;
}
public List<Application> getApplications() {
return applications;
}
public Map<String, String> getCompany() {
return company;
}
public String getSecret() {
return secret;
}
public String getAuth_code() {
return auth_code;
}
public String getCompanyCode() {
return company_code;
}
private void setCode (String company_code){
this.company_code = company_code;
}
public static void setCompanyCode(String company_code) {
License.license.setCode(company_code);
if (company_code != null){
CompanyValid.setHad(true);
}
}
}

View File

@ -0,0 +1,53 @@
package cn.crtech.cloud.licenseAnalysis.pojo;
public class Param {
@Override
protected Param clone() {
Param tmp = new Param();
tmp.code = this.code;
tmp.name = this.name;
tmp.description = this.description;
tmp.value = this.value;
tmp.valueType = this.valueType;
tmp.falseDefault = this.falseDefault;
tmp.trueDefault = this.trueDefault;
return tmp;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String getValue() {
return value;
}
public String getValueType() {
return valueType;
}
public String getFalseDefault() {
return falseDefault;
}
public String getTrueDefault() {
return trueDefault;
}
protected String code;
protected String name;
protected String description;
protected String value;
protected String valueType;
protected String falseDefault;
protected String trueDefault;
}

View File

@ -0,0 +1,100 @@
package cn.crtech.cloud.licenseAnalysis.utils;
import org.springframework.util.Base64Utils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @version V1.0
* @desc AES 加密工具类
*/
public class AESUtil {
private static final String KEY_ALGORITHM = "AES";
/**
* 默认的加密算法
*/
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
/**
* AES 加密操作
*
* @param content 待加密内容
* @param password 加密密码
* @return 返回Base64转码后的加密数据
*/
public static String encrypt(String content, String password) {
try {
// 创建密码器
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
byte[] byteContent = content.getBytes("utf-8");
// 初始化为加密模式的密码器
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));
// 加密
byte[] result = cipher.doFinal(byteContent);
//通过Base64转码返回
return Base64Utils.encodeToString(result);
} catch (Exception ex) {
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
/**
* AES 解密操作
*
* @param content 字符串内容
* @param password 解码秘钥
* @return 返回操作
*/
public static String decrypt(String content, String password) {
try {
//实例化
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
//使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));
//执行操作
byte[] result = cipher.doFinal(Base64Utils.decodeFromString(content));
String s = new String(result, "utf-8");
return s;
} catch (Exception ex) {
ex.printStackTrace();
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
/**
* 生成加密秘钥
*
* @return 返回处理结果
*/
private static SecretKeySpec getSecretKey(String password) {
//返回生成指定算法密钥生成器的 KeyGenerator 对象
KeyGenerator kg = null;
try {
kg = KeyGenerator.getInstance(KEY_ALGORITHM);
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(password.getBytes());
//AES 要求密钥长度为 128
kg.init(128, random);
//生成一个密钥
SecretKey secretKey = kg.generateKey();
return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}

View File

@ -0,0 +1,66 @@
package cn.crtech.cloud.licenseAnalysis.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
public class MD5 {
private static final String key;
private static final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
static {
key = "aa";
}
public final static String md5(String s) {
if (s == null) return null;
return md5(s.getBytes());
}
public final static String md5(File file) {
if (file == null) return null;
if (!file.exists()) return null;
byte bytes[] = new byte[(int) file.length()];
FileInputStream fio = null;
try {
fio = new FileInputStream(file);
fio.read(bytes);
return md5(bytes);
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if (fio != null) {
try {
fio.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public final static String md5(byte[] bytes) {
try {
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(bytes);
byte[] md = mdTemp.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
}
public final static String md5() {
return md5(key);
}
}

View File

@ -0,0 +1,48 @@
package cn.crtech.cloud.licenseAnalysis.utils;
import oshi.hardware.CentralProcessor;
import oshi.hardware.ComputerSystem;
import oshi.hardware.HWDiskStore;
import oshi.hardware.HardwareAbstractionLayer;
import java.util.List;
/**
* @author inaisen
*/
public class MachineInfo {
static oshi.SystemInfo si = new oshi.SystemInfo();
static HardwareAbstractionLayer hal = si.getHardware();
/**
* 主板序列号
*/
public static String getSerialnumber() {
ComputerSystem computerSystem = hal.getComputerSystem();
return computerSystem.getSerialNumber();
}
/**
* 处理器ID
*/
public static String getprocessorid() {
CentralProcessor processor = hal.getProcessor();
return processor.getProcessorIdentifier().getProcessorID();
}
/**
* 硬盘SN
*/
public static String getDisksNumber() {
String disksNumber = null;
List<HWDiskStore> diskStores = hal.getDiskStores();
if (diskStores.size() > 0) {
for (HWDiskStore disk : diskStores) {
disksNumber = String.format("%s", disk.getSerial());
break;
}
}
return disksNumber;
}
}

View File

@ -0,0 +1,255 @@
package cn.crtech.cloud.licenseAnalysis.utils;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class Sha1WithRsaUtil {
/**
* 加密算法RSA
*/
public static final String RSA_ALGORITHM = "RSA";
/**
* 签名算法
* SHA1WithRSA MD5withRSA
*/
public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";
/**
* 字符串编码
*/
public static final String CHARSET = "UTF-8";
/**
* 根据RSA初始公钥 转化为 X509公钥
*
* @param publicKey 密钥字符串经过base64编码
*/
public static RSAPublicKey getPublicKeyX509(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
// 通过X509编码的Key指令获得公钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
return (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
}
/**
* 解密操作
* PKCS8 私钥解密(对应 X509 公钥加密)或者 X509 公钥解密(对应 PKCS8 私钥进行加密)
*/
public static String decrypt(String data, Key key) {
BigInteger modulus = keyModulus(key);
Cipher cipher = cipherInstance(Cipher.DECRYPT_MODE, key);
byte[] bytes = rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data),
modulus.bitLength());
try {
return new String(bytes, CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("RSA解密失败", e);
}
}
/**
* RSA 验签
*
* @return 布尔值
*/
public static boolean verify(String content, String sign, String publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
byte[] encodedKey = Base64.decodeBase64(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(content.getBytes(CHARSET));
return signature.verify(Base64.decodeBase64(sign));
} catch (Exception e) {
throw new RuntimeException("RSA 验签失败", e);
}
}
/**
* 分段处理
*
* @return 返回数据集合
*/
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
int maxBlock = 0;
if (opmode == Cipher.DECRYPT_MODE) {
maxBlock = keySize / 8;
} else {
maxBlock = keySize / 8 - 11;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] buff;
byte[] resultDatas;
Exception e1;
int i = 0;
try {
while (datas.length > offSet) {
if (datas.length - offSet > maxBlock) {
buff = cipher.doFinal(datas, offSet, maxBlock);
} else {
buff = cipher.doFinal(datas, offSet, datas.length - offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
resultDatas = out.toByteArray();
} catch (Exception e) {
throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
} finally {
try {
out.close();
} catch (IOException e) {
throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时,关闭流发生异常", e);
}
}
return resultDatas;
}
/**
* 获取加密key的 实例
*/
private static Cipher cipherInstance(int mode, Key key) {
Cipher cipher = null;
try {
cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(mode, key);
} catch (Exception e) {
throw new RuntimeException("获取Cipher 实例异常:", e);
}
return cipher;
}
private static BigInteger keyModulus(Key key) {
BigInteger modulus = null;
if (key instanceof RSAPublicKey) {
modulus = ((RSAPublicKey) key).getModulus();
} else if (key instanceof RSAPrivateKey) {
modulus = ((RSAPrivateKey) key).getModulus();
}
return modulus;
}
/**
* 据说1024 加密不安全,默认 走2048加密
*/
public static final int keySize = 2048;
/**
* 创建RSA 原始的公钥私钥
*
* @return 返回生成结果
*/
public static Map<String, String> createKeys() {
return createKeys(keySize);
}
/**
* 获取初始的公钥和私钥
* 1024 2048
*
* @param keySize 长度
*/
private static Map<String, String> createKeys(int keySize) {
// 为RSA算法创建一个KeyPairGenerator对象
KeyPairGenerator kpg;
try {
kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
}
// 初始化KeyPairGenerator对象,密钥长度
kpg.initialize(keySize);
// 生成密匙对
KeyPair keyPair = kpg.generateKeyPair();
// 得到公钥
Key publicKey = keyPair.getPublic();
String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
// 得到私钥
Key privateKey = keyPair.getPrivate();
String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
Map<String, String> keyPairMap = new HashMap<String, String>();
keyPairMap.put("publicKey", publicKeyStr);
keyPairMap.put("privateKey", privateKeyStr);
return keyPairMap;
}
/**
* RSA签名
*
* @param content 待签名数据
* @param privateKey 私钥
* @return 签名值
*/
public static String sign(String content, String privateKey) {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
KeyFactory keyf = KeyFactory.getInstance(RSA_ALGORITHM);
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update(content.getBytes(CHARSET));
byte[] signed = signature.sign();
return Base64.encodeBase64URLSafeString(signed);
} catch (Exception e) {
throw new RuntimeException("签名发生异常", e);
}
}
/**
* 加密操作
* X509 公钥加密(对应 PKCS8 私钥进行解密) 或者 PKCS8 私钥加密(对应X509公钥解密)
*/
public static String encrypt(String data, Key key) {
BigInteger modulus = keyModulus(key);
try {
Cipher cipher = cipherInstance(Cipher.ENCRYPT_MODE, key);
byte[] bytes = rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET),
modulus.bitLength());
return Base64.encodeBase64URLSafeString(bytes);
} catch (Exception e) {
throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
}
}
/**
* 根据RSA初始私钥 转化为 PKCS8私钥
*
* @param privateKey 密钥字符串经过base64编码
*/
public static RSAPrivateKey getPrivateKeyPkcs8(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
// 通过PKCS#8编码的Key指令获得私钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
return key;
}
}

View File

@ -0,0 +1,36 @@
package cn.crtech.cloud.licenseAnalysis.utils;
import java.io.File;
/**
* desc
*
* @author: TYP
* @date: 2022-12-28 8:57
*/
public class StaticResource {
public static final String RUN_PATH = System.getProperty("user.dir");
public static final String FILE_PATH = System.getProperty("user.dir") + File.separator + "src" +
File.separator + "main" + File.separator + "resources" + File.separator + "conf";
public static final String CONFIG_PATH = "conf";
public static final String WEBAPPS_PATH = "apps";
public static final String ADMIN_CONTEXT = "xinadmin";
private static final String CONFIG_FILE = "XinLauncher.ini";
public static final String CHIPER_FILE = "XinLauncher.data";
public static final String LICENSE = "license.data";
private static final String HOSTS_FILE = "Dev-Hosts.xml";
private static boolean is_dev = false;
public static boolean isDev() {
return is_dev;
}
}

View File

@ -0,0 +1,337 @@
package cn.crtech.cloud.licenseAnalysis.utils;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* launcher 日志记录实体类
*
* @Author: TYP
* @Date: 2022-09-27 11:34
*/
public class SystemLogger {
// 日志文件地址
private static final String LOG_FILE_PATH = System.getProperty("user.dir") + File.separator + "logs" + File.separator;
// 日志文件前缀名
private static final String LOG_FILE_NAME = "XinLaucher";
// 日志文件编码格式
private static final String LOG_FILE_ENCODING = "UTF-8";
private static final SimpleDateFormat TIME_SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final SimpleDateFormat DATE_SDF = new SimpleDateFormat("yyyy-MM-dd");
private static final int LOG_LEVEL = 3;
private String classPath;
public SystemLogger(Class<?> clzz) {
this.classPath = clzz.getName();
}
public void info(String message) {
Date date = new Date();
String time = TIME_SDF.format(date);
StringBuffer outMsg = new StringBuffer(time + " == [" + this.classPath + "] [INFO] ==> : " + message);
String file_suffix = DATE_SDF.format(date);
String fileName = LOG_FILE_PATH + LOG_FILE_NAME + file_suffix + ".log";
File file = checkFile(fileName);
if (file != null) {
System.out.println(outMsg.toString());
if (LOG_LEVEL >= 1) {
appendMethod(file, outMsg.toString());
}
}
}
public void info(String message, Object... data) {
if (data.length < 1) {
info(message);
} else {
String[] splitStr = message.split("\\{\\}");
if (splitStr.length != data.length && splitStr.length != (data.length + 1)) {
new Exception("日志数据输出异常替换个数不一致,日志数据记录失败!").fillInStackTrace();
} else {
Date date = new Date();
String time = TIME_SDF.format(date);
StringBuffer outMsg = new StringBuffer(time + " == [" + this.classPath + "] [INFO] ==> : ");
if (splitStr.length == data.length) {
for (int i = 0; i <= (splitStr.length - 1); i++) {
outMsg.append(splitStr[i] + data[i]);
}
} else {
for (int i = 0; i <= (splitStr.length - 1); i++) {
outMsg.append(splitStr[i]);
if (i < (splitStr.length - 1)) {
outMsg.append(data[i]);
}
}
}
String file_suffix = DATE_SDF.format(date);
String fileName = LOG_FILE_PATH + LOG_FILE_NAME + file_suffix + ".log";
File file = checkFile(fileName);
if (file != null) {
System.out.println(outMsg.toString());
if (LOG_LEVEL >= 1) {
appendMethod(file, outMsg.toString());
}
}
}
}
}
public void debug(String message) {
Date date = new Date();
String time = TIME_SDF.format(date);
StringBuffer outMsg = new StringBuffer(time + " == [" + this.classPath + "] [DEBUG] ==> : " + message);
String file_suffix = DATE_SDF.format(date);
String fileName = LOG_FILE_PATH + LOG_FILE_NAME + file_suffix + ".log";
File file = checkFile(fileName);
if (file != null) {
System.out.println(outMsg.toString());
if (LOG_LEVEL >= 2) {
appendMethod(file, outMsg.toString());
}
}
}
public void debug(String message, Object... data) {
if (data.length < 1) {
info(message);
} else {
String[] splitStr = message.split("\\{\\}");
if (splitStr.length != data.length && splitStr.length != (data.length + 1)) {
new Exception("日志数据输出异常替换个数不一致,日志数据记录失败!").fillInStackTrace();
} else {
Date date = new Date();
String time = TIME_SDF.format(date);
StringBuffer outMsg = new StringBuffer(time + " == [" + this.classPath + "] [DEBUG] ==> : ");
if (splitStr.length == data.length) {
for (int i = 0; i <= (splitStr.length - 1); i++) {
outMsg.append(splitStr[i] + data[i]);
}
} else {
for (int i = 0; i <= (splitStr.length - 1); i++) {
outMsg.append(splitStr[i]);
if (i < (splitStr.length - 1)) {
outMsg.append(data[i]);
}
}
}
String file_suffix = DATE_SDF.format(date);
String fileName = LOG_FILE_PATH + LOG_FILE_NAME + file_suffix + ".log";
File file = checkFile(fileName);
if (file != null) {
System.out.println(outMsg.toString());
if (LOG_LEVEL >= 2) {
appendMethod(file, outMsg.toString());
}
}
}
}
}
public void error(String message) {
Date date = new Date();
String time = TIME_SDF.format(date);
StringBuffer outMsg = new StringBuffer(time + " == [" + this.classPath + "] [ERROR] ==> : " + message);
String file_suffix = DATE_SDF.format(date);
String fileName = LOG_FILE_PATH + LOG_FILE_NAME + file_suffix + ".log";
File file = checkFile(fileName);
if (file != null) {
System.err.println(outMsg.toString());
if (LOG_LEVEL >= 3) {
appendMethod(file, outMsg.toString());
}
}
}
public void error(String message, Object... data) {
if (data.length < 1) {
info(message);
} else {
String[] splitStr = message.split("\\{\\}");
if (splitStr.length != data.length && splitStr.length != (data.length + 1)) {
new Exception("日志数据输出异常替换个数不一致,日志数据记录失败!").fillInStackTrace();
} else {
Date date = new Date();
String time = TIME_SDF.format(date);
StringBuffer outMsg = new StringBuffer(time + " == [" + this.classPath + "] [ERROR] ==> : ");
if (splitStr.length == data.length) {
for (int i = 0; i <= (splitStr.length - 1); i++) {
outMsg.append(splitStr[i] + data[i]);
}
} else {
for (int i = 0; i <= (splitStr.length - 1); i++) {
outMsg.append(splitStr[i]);
if (i < (splitStr.length - 1)) {
outMsg.append(data[i]);
}
}
}
String file_suffix = DATE_SDF.format(date);
String fileName = LOG_FILE_PATH + LOG_FILE_NAME + file_suffix + ".log";
File file = checkFile(fileName);
if (file != null) {
System.err.println(outMsg.toString());
if (LOG_LEVEL >= 3) {
appendMethod(file, outMsg.toString());
}
}
}
}
}
public void warn(String message) {
Date date = new Date();
String time = TIME_SDF.format(date);
StringBuffer outMsg = new StringBuffer(time + " == [" + this.classPath + "] [WARN] ==> : " + message);
String file_suffix = DATE_SDF.format(date);
String fileName = LOG_FILE_PATH + LOG_FILE_NAME + file_suffix + ".log";
File file = checkFile(fileName);
if (file != null) {
System.err.println(outMsg.toString());
if (LOG_LEVEL >= 4) {
appendMethod(file, outMsg.toString());
}
}
}
public void warn(String message, Object... data) {
if (data.length < 1) {
info(message);
} else {
String[] splitStr = message.split("\\{\\}");
if (splitStr.length != data.length && splitStr.length != (data.length + 1)) {
new Exception("日志数据输出异常替换个数不一致,日志数据记录失败!").fillInStackTrace();
} else {
Date date = new Date();
String time = TIME_SDF.format(date);
StringBuffer outMsg = new StringBuffer(time + " == [" + this.classPath + "] [WARN] ==> : ");
if (splitStr.length == data.length) {
for (int i = 0; i <= (splitStr.length - 1); i++) {
outMsg.append(splitStr[i] + data[i]);
}
} else {
for (int i = 0; i <= (splitStr.length - 1); i++) {
outMsg.append(splitStr[i]);
if (i < (splitStr.length - 1)) {
outMsg.append(data[i]);
}
}
}
String file_suffix = DATE_SDF.format(date);
String fileName = LOG_FILE_PATH + LOG_FILE_NAME + file_suffix + ".log";
File file = checkFile(fileName);
if (file != null) {
System.err.println(outMsg.toString());
if (LOG_LEVEL >= 4) {
appendMethod(file, outMsg.toString());
}
}
}
}
}
public void fatal(String message) {
Date date = new Date();
String time = TIME_SDF.format(date);
StringBuffer outMsg = new StringBuffer(time + " == [" + this.classPath + "] [FATAL] ==> : " + message);
String file_suffix = DATE_SDF.format(date);
String fileName = LOG_FILE_PATH + LOG_FILE_NAME + file_suffix + ".log";
File file = checkFile(fileName);
if (file != null) {
System.err.println(outMsg.toString());
if (LOG_LEVEL >= 5) {
appendMethod(file, outMsg.toString());
}
}
}
public void fatal(String message, Object... data) {
if (data.length < 1) {
info(message);
} else {
String[] splitStr = message.split("\\{\\}");
if (splitStr.length != data.length && splitStr.length != (data.length + 1)) {
new Exception("日志数据输出异常替换个数不一致,日志数据记录失败!").fillInStackTrace();
} else {
Date date = new Date();
String time = TIME_SDF.format(date);
StringBuffer outMsg = new StringBuffer(time + " == [" + this.classPath + "] [FATAL] ==> : ");
if (splitStr.length == data.length) {
for (int i = 0; i <= (splitStr.length - 1); i++) {
outMsg.append(splitStr[i] + data[i]);
}
} else {
for (int i = 0; i <= (splitStr.length - 1); i++) {
outMsg.append(splitStr[i]);
if (i < (splitStr.length - 1)) {
outMsg.append(data[i]);
}
}
}
String file_suffix = DATE_SDF.format(date);
String fileName = LOG_FILE_PATH + LOG_FILE_NAME + file_suffix + ".log";
File file = checkFile(fileName);
if (file != null) {
System.err.println(outMsg.toString());
if (LOG_LEVEL >= 5) {
appendMethod(file, outMsg.toString());
}
}
}
}
}
private static File checkFile(String fileName) {
File file = new File(fileName);
if (!file.exists()) {
int position = fileName.lastIndexOf(File.separator);
String packageName = fileName.substring(0, position);
File packageFile = new File(packageName);
if (!packageFile.exists()) {
packageFile.mkdirs();
}
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
return file;
}
private static void appendMethod(File file, String content) {
try {
FileWriter writer = new FileWriter(file, true);
writer.write(content + "\n");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}