diff --git a/entrance/src/main/resources/application.yml b/entrance/src/main/resources/application.yml index 591765ad..e07a1902 100644 --- a/entrance/src/main/resources/application.yml +++ b/entrance/src/main/resources/application.yml @@ -118,7 +118,7 @@ power-quality: harmonic-times: 50 # 谐波次数 ib-add: false # 电流基波叠加标志 uharm-add: false # 电压谐波叠加标志 -# rsa公私钥 -rsa: +# 激活配置 +activate: private-key: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCcUyYhVqczGxblL+o/xZzF/8nf+LjrfUE/dS1aRHM7uMDD0cgCArhjtfneFePrMxt+Z7W8yNBzSarub8qsfhaVNikV7Es7oaeTygfjQXTi2n4AFkir3fM07J08RpWhl5M8f8uWTCuvFUYAw00gq55typqmnbkmJa2VIUy/iQf+cMCP7abz4/jNhUzUR3qA7TV4oMRgTdIEDUp63YF8dOC+JH8XxYrCVeHXV6fLCwmesdMzl0lB2VTEKMfLbXhOmF5g7P9y/16VCcN8UBuZlbyYfn+GAxJOSbeHi5HshOKfoSuD7Jz+3WQZpNavOWjIFExKIU38/CvnJCOP7XBCqpSTAgMBAAECggEAYeWokWRE3TpvwiOZnUpR/aVMdVi75a3ROL5XIpqPV61B+t/bU3cEpl0GF9C5pUeiRi0IoStZb3mI9D1KPW/REKyUWkhabQO1gFYbTnRlkNOn6MILzKX4cwJjDaZeeo4EBPU7N+qHyOOXrU6hdH5FfxhMdV983ajm5eeuupxER1C2kAcIklTeVpTX6EKOgZb5LBp5ssOVm2P42pOauvcRozRcvZmqnErXmukv0H4l3EVNt4rHpTn9riHUC63e8JfiYzVaF6zuNUxv6nHEft0/SRMw11XSTnNfDzcKqgjz6ksFBS/6eQQYKESk+ONC53HUuYHFAknkwsPupDCT2W8FIQKBgQDLHT/xCU3nxGr4vFKBDNaO2D5oK20ECbBO4oDvLWWmQG7f+6TsMy8PgVdMnoL4RfqGlwFAKEpS6KVFHnBVqnNEhcdy9uCI7x7Xx8UnyUtxj1EDTm76uta9Ki9OrlqB6tImDM9+Ya3vGktW37ht4WOx2OsJRhG1dbf6RLwFlH7DWwKBgQDFBxvi5I1BR6hg6Tj7xd2SqOT2Y+BED3xuSYENhWbmMhLJDResaB7mjztbxlYaY2mOE0holWm2uDmVFFhMh4jYXik4hYH8nmDzq9mDpZCZ9pyjYqnAP8THoAa8EbgrUWB8A6BPH4iL3KbMnBfBKY0pIr2xrvnjQjNBAgta7KDRKQKBgCe6oe4wxrdF2TKsC2tIqpMoQxS3Icy/ZGgZr+SYuaBKTCWtoDW/UT40K3JGMxIDBhzbXphBCUCsVt9tM8Xd4EwP6tJW7dZ7B0pnve2pVwNwaAVAiz6p2yUHIle+jN+Koe5lZRSwYIg7WW81tWpwwsJfzqFyvjYDP6hJV4mz4ROvAoGAaRcdnKvjXApomShMqJ4lTPChD3q+SA8qg3jZSOj6tZXHx00gb2kp8jg7pPvpOTIFPy6x1Ha9aCRjMk0ju84fA6lVuzwa1S907wOehUVuF3Eeo1cgy9Y3k3KbpPyeixxgpkUY4JslLdSHc2NemD0dee951qhJyRmqVOZOQDUuoeECgYEAqBw2cAFk3vM97WY06TSldGA8ajVHx3BYRjj+zl62NTQthy8fw3tqxb3c5e8toOmZWKjZvDhg2TRLhsDDQWEYg3LZG87REqVIjgEPcpjNLidjygGX8n3JF2o0O5I/EMvl0s/+LVQONfduOBvhwDqr8QNisbLsyneiAq7umewMolo=" public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnFMmIVanMxsW5S/qP8Wcxf/J3/i4631BP3UtWkRzO7jAw9HIAgK4Y7X53hXj6zMbfme1vMjQc0mq7m/KrH4WlTYpFexLO6Gnk8oH40F04tp+ABZIq93zNOydPEaVoZeTPH/LlkwrrxVGAMNNIKuebcqapp25JiWtlSFMv4kH/nDAj+2m8+P4zYVM1Ed6gO01eKDEYE3SBA1Ket2BfHTgviR/F8WKwlXh11enywsJnrHTM5dJQdlUxCjHy214TpheYOz/cv9elQnDfFAbmZW8mH5/hgMSTkm3h4uR7ITin6Erg+yc/t1kGaTWrzloyBRMSiFN/Pwr5yQjj+1wQqqUkwIDAQAB" \ No newline at end of file diff --git a/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/config/ActivateProperties.java b/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/config/ActivateProperties.java new file mode 100644 index 00000000..a0c4fd8d --- /dev/null +++ b/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/config/ActivateProperties.java @@ -0,0 +1,33 @@ +package com.njcn.gather.tool.active.config; + +import cn.hutool.system.SystemUtil; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.io.File; + +@Data +@ConfigurationProperties(prefix = "activate") +public class ActivateProperties { + private final String LICENSE_FILE_NAME = "license.key"; + + /** + * RSA公钥 + */ + private String publicKey; + /** + * RSA私钥 + */ + private String privateKey; + + /** + * 密钥文件所在目录,默认为当前项目目录 + */ + private String licenseDir = System.getProperty(SystemUtil.USER_DIR); + + public String getLicenseFilePath() { + return licenseDir + File.separator + LICENSE_FILE_NAME; + } + + +} diff --git a/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/config/RSAProperties.java b/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/config/RSAProperties.java deleted file mode 100644 index c24e4700..00000000 --- a/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/config/RSAProperties.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.njcn.gather.tool.active.config; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@Data -@ConfigurationProperties(prefix = "rsa") -public class RSAProperties { - /** - * RSA公钥 - */ - private String publicKey; - /** - * RSA私钥 - */ - private String privateKey; -} diff --git a/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/controller/ActivateController.java b/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/controller/ActivateController.java index 502ea945..63b27ef1 100644 --- a/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/controller/ActivateController.java +++ b/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/controller/ActivateController.java @@ -1,5 +1,7 @@ package com.njcn.gather.tool.active.controller; +import cn.hutool.core.net.NetUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.njcn.common.pojo.annotation.OperateInfo; import com.njcn.common.pojo.enums.common.LogEnum; @@ -58,10 +60,26 @@ public class ActivateController extends BaseController { String methodDescribe = getMethodDescribe("checkLicense"); LogUtil.njcnDebug(log, "{},获取许可信息", methodDescribe); ActivationCodePlaintext activationCodePlaintext = activateService.readLicenseFile(); + String macAddress = NetUtil.getLocalMacAddress(); if (activationCodePlaintext == null) { activationCodePlaintext = new ActivationCodePlaintext(); + activationCodePlaintext.setMacAddress(macAddress); activationCodePlaintext.init(); + } else { + // 校验mac地址 + String licenseMacAddress = activationCodePlaintext.getMacAddress(); + if (StrUtil.isNotEmpty(licenseMacAddress)) { + if (!StrUtil.equals(licenseMacAddress, macAddress)) { + log.error("mac地址不匹配,无效的许可文件,本机mac:{},许可mac:{}", macAddress, licenseMacAddress); + methodDescribe = "mac地址不匹配,无效的许可文件"; + activationCodePlaintext = new ActivationCodePlaintext(); + activationCodePlaintext.setMacAddress(macAddress); + activationCodePlaintext.init(); + } + } } + + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, activationCodePlaintext, methodDescribe); } diff --git a/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/service/impl/ActivateServiceImpl.java b/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/service/impl/ActivateServiceImpl.java index e57e4765..178de594 100644 --- a/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/service/impl/ActivateServiceImpl.java +++ b/tools/activate-tool/src/main/java/com/njcn/gather/tool/active/service/impl/ActivateServiceImpl.java @@ -7,7 +7,7 @@ import cn.hutool.json.JSONUtil; import com.njcn.common.pojo.enums.response.CommonResponseEnum; import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.utils.RSAUtil; -import com.njcn.gather.tool.active.config.RSAProperties; +import com.njcn.gather.tool.active.config.ActivateProperties; import com.njcn.gather.tool.active.service.ActivateService; import com.njcn.gather.tool.active.vo.ActivationCodePlaintext; import com.njcn.gather.tool.active.vo.ActivationModule; @@ -17,17 +17,13 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.stereotype.Service; -import java.io.File; - -@EnableConfigurationProperties(RSAProperties.class) +@EnableConfigurationProperties(ActivateProperties.class) @RequiredArgsConstructor @Slf4j @Service public class ActivateServiceImpl implements ActivateService { - private final RSAProperties rsaProperties; - static final String LICENSE_FILE_NAME = "license.key"; - static final String LICENSE_FILE_PATH = ActivateServiceImpl.class.getProtectionDomain().getCodeSource().getLocation().getPath() + File.separator + LICENSE_FILE_NAME; + private final ActivateProperties props; @Override public String generateApplicationCode(ApplicationCodePlaintext data) { @@ -38,7 +34,7 @@ public class ActivateServiceImpl implements ActivateService { String plaintext = JSONUtil.toJsonStr(data); // RSA 加密 try { - return RSAUtil.encrypt(plaintext, RSAUtil.stringToPublicKey(rsaProperties.getPublicKey())); + return RSAUtil.encrypt(plaintext, RSAUtil.stringToPublicKey(props.getPublicKey())); } catch (Exception e) { log.error("申请码加密失败", e); throw new BusinessException(CommonResponseEnum.FAIL, "申请码生成失败"); @@ -49,7 +45,7 @@ public class ActivateServiceImpl implements ActivateService { public ActivationCodePlaintext verifyActivationCode(String activationCode) { String plaintext; try { - plaintext = RSAUtil.decrypt(activationCode, RSAUtil.stringToPrivateKey(rsaProperties.getPrivateKey())); + plaintext = RSAUtil.decrypt(activationCode, RSAUtil.stringToPrivateKey(props.getPrivateKey())); } catch (Exception e) { log.error("授权码解密失败", e); throw new BusinessException(CommonResponseEnum.FAIL, "无效的激活码"); @@ -66,11 +62,13 @@ public class ActivateServiceImpl implements ActivateService { @Override public ActivationCodePlaintext readLicenseFile() { - if (FileUtil.exist(LICENSE_FILE_PATH)) { - String content = FileUtil.readUtf8String(LICENSE_FILE_PATH); + String licenseFilePath = props.getLicenseFilePath(); + log.info("读取授权文件,{}", licenseFilePath); + if (FileUtil.exist(licenseFilePath)) { + String content = FileUtil.readUtf8String(licenseFilePath); String plaintext; try { - plaintext = RSAUtil.decrypt(content, RSAUtil.stringToPrivateKey(rsaProperties.getPrivateKey())); + plaintext = RSAUtil.decrypt(content, RSAUtil.stringToPrivateKey(props.getPrivateKey())); } catch (Exception e) { log.error("授权文件内容解密失败", e); throw new BusinessException(CommonResponseEnum.FAIL, "许可信息读取失败"); @@ -85,7 +83,7 @@ public class ActivateServiceImpl implements ActivateService { // RSA 解密 String plaintext; try { - plaintext = RSAUtil.decrypt(applicationCode, RSAUtil.stringToPrivateKey(rsaProperties.getPrivateKey())); + plaintext = RSAUtil.decrypt(applicationCode, RSAUtil.stringToPrivateKey(props.getPrivateKey())); } catch (Exception e) { log.error("申请码解密失败", e); throw new BusinessException(CommonResponseEnum.FAIL, "无效的申请码"); @@ -115,7 +113,7 @@ public class ActivateServiceImpl implements ActivateService { String jsonStr = JSONUtil.toJsonStr(activationCodePlaintext); log.info("生成激活码明文:{}", jsonStr); try { - return RSAUtil.encrypt(jsonStr, RSAUtil.stringToPublicKey(rsaProperties.getPublicKey())); + return RSAUtil.encrypt(jsonStr, RSAUtil.stringToPublicKey(props.getPublicKey())); } catch (Exception e) { log.error("生成激活码失败", e); throw new BusinessException(CommonResponseEnum.FAIL, "生成激活码失败"); @@ -125,11 +123,12 @@ public class ActivateServiceImpl implements ActivateService { /** * 添加或更新授权文件 * - * @param newActivationCodePlaintext - * @param activationCode - * @return + * @param newActivationCodePlaintext 新授权码明文 + * @param activationCode 授权码 + * @return 最新授权码明文 */ private ActivationCodePlaintext addOrUpdateLicenseFile(ActivationCodePlaintext newActivationCodePlaintext, String activationCode) { + log.info("新授权码明文:{}", JSONUtil.toJsonStr(newActivationCodePlaintext)); ActivationModule newContrast = newActivationCodePlaintext.getContrast(); ActivationModule newDigital = newActivationCodePlaintext.getDigital(); @@ -148,16 +147,18 @@ public class ActivateServiceImpl implements ActivateService { log.error("授权码格式错误"); throw new BusinessException(CommonResponseEnum.FAIL, "无效的激活码"); } - log.info("授权文件路径:{}", LICENSE_FILE_PATH); + String licenseFilePath = props.getLicenseFilePath(); + log.info("授权文件路径:{}", licenseFilePath); ActivationCodePlaintext oldActivationCodePlaintext = this.readLicenseFile(); if (oldActivationCodePlaintext == null) { // 如果文件不存在,创建新文件 - FileUtil.touch(LICENSE_FILE_PATH); + FileUtil.touch(licenseFilePath); // 写入授权文件 - FileUtil.writeUtf8String(activationCode, LICENSE_FILE_PATH); + FileUtil.writeUtf8String(activationCode, licenseFilePath); return newActivationCodePlaintext; } else { log.info("旧授权码明文:{}", JSONUtil.toJsonStr(oldActivationCodePlaintext)); + oldActivationCodePlaintext.setMacAddress(newActivationCodePlaintext.getMacAddress()); if (newContrast.isApply()) { oldActivationCodePlaintext.setContrast(newContrast); } @@ -171,12 +172,12 @@ public class ActivateServiceImpl implements ActivateService { String updateContent; // 重新加密 try { - updateContent = RSAUtil.encrypt(JSONUtil.toJsonStr(oldActivationCodePlaintext), RSAUtil.stringToPublicKey(rsaProperties.getPublicKey())); + updateContent = RSAUtil.encrypt(JSONUtil.toJsonStr(oldActivationCodePlaintext), RSAUtil.stringToPublicKey(props.getPublicKey())); } catch (Exception e) { log.error("授权文件内容加密失败", e); throw new BusinessException(CommonResponseEnum.FAIL, "激活失败,请联系管理员"); } - FileUtil.writeUtf8String(updateContent, LICENSE_FILE_PATH); + FileUtil.writeUtf8String(updateContent, licenseFilePath); return oldActivationCodePlaintext; } }