diff --git a/LicenseAnalysis/pom.xml b/LicenseAnalysis/pom.xml
new file mode 100644
index 0000000..f5d1b38
--- /dev/null
+++ b/LicenseAnalysis/pom.xml
@@ -0,0 +1,88 @@
+
+
+ 4.0.0
+
+ cn.crtech.license_analysis
+ LicenseAnalysis
+ 1.0.1
+
+
+
+ cn.crtech.cloud.dependencies
+ Dependencies
+ 1.0.1
+
+
+
+
+
+ 8
+ 8
+ 1.8
+ UTF-8
+
+ 5.8.3
+ 1.2.83
+ 1.9.13
+ 2.1.3
+ 1.0.1
+
+
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ commons-codec
+ commons-codec
+
+
+
+ org.springframework
+ spring-core
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+ com.google.code.gson
+ gson
+
+
+
+
+ com.github.oshi
+ oshi-core
+ ${oshi.version}
+
+
+
+
+ com.alibaba
+ fastjson
+ ${fastjson.version}
+
+
+
+
+ org.codehaus.jackson
+ jackson-mapper-asl
+ ${jackson.version}
+
+
+
+ org.dom4j
+ dom4j
+ ${dom4j.version}
+
+
+
diff --git a/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/api/Result.java b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/api/Result.java
new file mode 100644
index 0000000..3b5db56
--- /dev/null
+++ b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/api/Result.java
@@ -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;
+ }
+}
diff --git a/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/api/ResultCode.java b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/api/ResultCode.java
new file mode 100644
index 0000000..d7cbd27
--- /dev/null
+++ b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/api/ResultCode.java
@@ -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();
+ }
+}
diff --git a/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/CompanyValid.java b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/CompanyValid.java
new file mode 100644
index 0000000..12402ac
--- /dev/null
+++ b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/CompanyValid.java
@@ -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);
+ }
+}
diff --git a/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/LauncherValid.java b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/LauncherValid.java
new file mode 100644
index 0000000..154bd13
--- /dev/null
+++ b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/LauncherValid.java
@@ -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 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 map = new HashMap();
+ 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 decodeMachineInfoKey(String machineInfoKey) throws Exception {
+ String key = generateKey();
+ String cipher = AESUtil.decrypt(machineInfoKey, key);
+ Map 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 machineInfoMap = decodeMachineInfoKey(machineInfoKey);
+
+ if (contentInfo == null || "".equals(contentInfo)) {
+ String key = generateKey();
+ contentInfo = AESUtil.decrypt(systemInfo, key);
+ }
+
+ if (!ObjectUtils.isEmpty(contentInfo) || !ObjectUtils.isEmpty(machineInfoMap)) {
+ Map 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;
+ }
+}
diff --git a/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/LicenseValid.java b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/LicenseValid.java
new file mode 100644
index 0000000..41297a6
--- /dev/null
+++ b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/LicenseValid.java
@@ -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 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 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 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 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 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();
+ }
+ }
+}
diff --git a/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/SystemInit.java b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/SystemInit.java
new file mode 100644
index 0000000..41227df
--- /dev/null
+++ b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/launcher/SystemInit.java
@@ -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 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 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("系统已有相关配置!不可重复配置!");
+ }
+ }
+}
diff --git a/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/pojo/Application.java b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/pojo/Application.java
new file mode 100644
index 0000000..2d68130
--- /dev/null
+++ b/LicenseAnalysis/src/main/java/cn/crtech/cloud/licenseAnalysis/pojo/Application.java
@@ -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 popedom : this.popedoms) {
+ Map 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