fix(*) 首次提交LicenseAnalysis项目
This commit is contained in:
88
LicenseAnalysis/pom.xml
Normal file
88
LicenseAnalysis/pom.xml
Normal 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>
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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("系统已有相关配置!不可重复配置!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user