赞
踩
整体设计思路 license服务器端: --负责根据客户端systemSign颁发证书。 --使用dom4j生成lic.xml证书 --使用AES对xml关键节点进行数据加密 --lic证书生成时设定信息包括: -----客户端systemSign -----生效起始时间 -----生效截止时间 -----上一次校验时间 -----项目版本号 -----license文件生成路径 license客户端: --负责生成systemSign客户端系统签名 --证书检验/定时验证/自助更新(手动替换) --API管控(无lic证书,则无法访问系统功能API) --证书校验逻辑: -----lic.xml文件存不存在 -----解析xml是否异常! -----解密signature签名是否成功 -----解析版本号、lic生成时间、lic过期时间、上一次校验时间 -----校验本机app版本号与license版本号是否不一致 -----校验mac地址与本机是否一致 -----校验cpu序列号与本机是否一致 ---证书过期判定: ------上次校验时间 大于当前系统时间 ------lic证书生成时间 大于当前系统时间 ------lic证书过期时间 小于当前系统时间
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.11</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.2-jre</version>
</dependency>
LinuxCmd.java 通过bash命令得到需要的硬件信息
package cn.test.lic.hardware; import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.util.Arrays; import java.util.List; /** * * 这里使用bash命令操作 dmidecode \ ip 等命令 返回需要的硬件信息 */ public class LinuxCmd { // public static void main(String[] args) throws IOException { // String serialNumber = getSerialNumber(); // String cpuNumber = getCpuNumber(); // String mac = getMAC(); // System.out.println(serialNumber); // System.out.println(cpuNumber); // System.out.println(mac); // } /** * 获取MAC地址 * @return 80:61:5f:13:93:29 * @throws IOException */ public static String getMAC() throws IOException { //[root@localhost ~]# ip addr show |grep 'link/ether' // link/ether 80:61:5f:13:93:29 brd ff:ff:ff:ff:ff:ff // link/ether 80:61:5f:13:93:2a brd ff:ff:ff:ff:ff:ff // link/ether 52:54:00:d6:1d:db brd ff:ff:ff:ff:ff:ff // link/ether 52:54:00:d6:1d:db brd ff:ff:ff:ff:ff:ff // link/ether 02:42:1b:79:ee:e9 brd ff:ff:ff:ff:ff:ff String desc = exec("ip addr show |grep 'link/ether'"); String[] split = desc.split("\n"); List<String> list = Arrays.asList(split); if (list.size() > 0) { String s = list.get(0); System.out.println(s); String[] s1 = s.split(" "); String s2 = s1[1]; System.out.println(s2); return s2; } else { return ""; } } //------------------------------------------------------------- // dmidecode 是linux系统提供的查看cpu相关硬件信息的工具 //----------------------------------------- /** * 获取linux的 Cpu ID * * @return String 11 0F 90 00 FF FB 8B 17 * @throws IOException */ public static String getCpuNumber() throws IOException { String desc = exec("dmidecode -t processor | grep 'ID'"); return handleBashRespStr(desc); } /** * 获取linux 序列号 * * @return String CD66393F * @throws IOException */ public static String getSerialNumber() throws IOException { String desc = exec("dmidecode | grep 'Serial Number'"); return handleBashRespStr(desc); } private static String handleBashRespStr(String desc) { String[] split = desc.split("\n"); List<String> list = Arrays.asList(split); if (list.size() > 0) { String s = list.get(0); String[] split1 = s.split(":"); String s1 = split1[1]; System.err.println(s1); return s1; } else { return ""; } } /** * 执行linux bash命令 * * @param bash 如 ifconfig * @return String * @throws IOException */ private static String exec(String bash) throws IOException { String[] cmdA = { "/bin/sh", "-c", bash}; Process process = Runtime.getRuntime().exec(cmdA); LineNumberReader br = new LineNumberReader(new InputStreamReader(process.getInputStream())); StringBuffer sb = new StringBuffer(); String line; while ((line = br.readLine()) != null) { System.out.println(line); line = line.trim(); if (line.length() > 0) { sb.append(line).append("\n"); } } return sb.toString(); } }
WmicCmd.java利用cmd命令操作wmic返回需要的硬件信息
package cn.test.lic.hardware; import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.util.Arrays; import java.util.List; /** * wmic是windows系统内置的查看硬件信息的工具 * 这里利用cmd命令操作wmic返回需要的硬件信息 */ public class WmicCmd { private static String execCmd(String cmd) throws IOException { String[] cmdA = { "cmd.exe","/c",cmd}; Process process = Runtime.getRuntime().exec(cmdA); LineNumberReader br = new LineNumberReader(new InputStreamReader(process.getInputStream(),"GBK")); StringBuffer sb = new StringBuffer(); String line; while ((line=br.readLine())!=null){ line = line.trim(); if (line.length()>0) { sb.append(line).append("\n"); } } return sb.toString(); } private static String handleCmdRespStr(String desc){ String[] split = desc.split("\n"); List<String> list = Arrays.asList(split); if (list.size()>1){ return list.get(1).trim(); }else { return ""; } } /** * 获取mac地址 * @return String MACAddress * 8C:EC:4B:55:0E:EC * 20:41:53:59:4E:FF * @throws IOException */ public static String getMacAddress() throws IOException { final String cmd = "wmic nicconfig get macaddress"; String desc = execCmd(cmd); return handleCmdRespStr(desc); } /** * 获取cpuId * @return String ProcessorId * BFEBFBFF000906E9 * @throws IOException */ public static String getCpuProcessorId() throws IOException { final String cmd = "wmic cpu get processorid"; String desc = execCmd(cmd); return handleCmdRespStr(desc); } /** * 获取bios序列号 * @return SerialNumber * H34C4N2 * @throws IOException */ public static String getBiosSerialNumber() throws IOException { final String cmd = "wmic bios get serialnumber"; String desc = execCmd(cmd); return handleCmdRespStr(desc); } /** * 获取 主板序列号 * @return String SerialNumber * /H34C4N2/CNWS2007CN02YV/ * @throws IOException */ public static String getBaseBoardSerialNumber() throws IOException { final String cmd = "wmic baseboard get serialnumber"; String desc = execCmd(cmd); return handleCmdRespStr(desc); } }
package cn.test.lic.util; import cn.hutool.core.codec.Base64; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.spec.SecretKeySpec; import java.security.SecureRandom; public class AESjjmUtils { /** * 定义1个默认的aes key */ private static final String DEFAULT_AES_SEAD_KEY = "20230609"; /** * 使用默认key快速加密 * @param ywStr String 原文 * @return String * @throws Exception */ public static String fastEncrypt(String ywStr) throws Exception { return encrypt(ywStr,DEFAULT_AES_SEAD_KEY); } /** * 使用默认key快速解密 * @param mwStr String 密文 * @return String * @throws Exception */ public static String fastDecrypt(String mwStr) throws Exception { return decrypt(mwStr,DEFAULT_AES_SEAD_KEY); } /** * AES 加密 * @param ywStr 原文 * @param aesSeedKey 加密key * @return String * @throws Exception */ public static String encrypt(String ywStr, String aesSeedKey) throws Exception { SecretKeySpec spec = getAesSecretKeySpec(aesSeedKey); //实例化Cipher Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); //使用密钥初始化,设置为加密模式 cipher.init(Cipher.ENCRYPT_MODE, spec); byte[] byteContent = ywStr.getBytes("utf-8"); byte[] result = cipher.doFinal(byteContent); String aesMw = Base64.encode(result); return aesMw; } /** * AES 解密 * @param mwStr 密文 * @param aesSeedKey 加密key * @return String */ public static String decrypt(String mwStr,String aesSeedKey) throws Exception { SecretKeySpec spec = getAesSecretKeySpec(aesSeedKey); //实例化 Cipher Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); //使用密钥初始化,设置为解密模式 cipher.init(Cipher.DECRYPT_MODE,spec); byte[] decodeBytes = Base64.decode(mwStr); byte[] result = cipher.doFinal(decodeBytes); String resStr = new String(result, "utf-8"); return resStr; } private static SecretKeySpec getAesSecretKeySpec(String aesSeedKey)throws Exception{ //AES 要求密钥长度为 128 SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); random.setSeed(aesSeedKey.getBytes()); //利用seed值,生成1个128位的key KeyGenerator kg = KeyGenerator.getInstance("AES"); kg.init(128, random); //生成一个密钥 return new SecretKeySpec(kg.generateKey().getEncoded(), "AES"); } }
UniHardwareUtil.java
package cn.test.lic.util; import cn.test.lic.hardware.LinuxCmd; import cn.test.lic.hardware.WmicCmd; import lombok.extern.slf4j.Slf4j; import java.io.IOException; @Slf4j public class UniHardwareUtil { public static String getMacAddr() throws IOException { String property = System.getProperty("os.name"); if (property.contains("Window")) { String mac = WmicCmd
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。