ard-admin/src/main/java/com/ard/web/controller/system/AuthorizationController.java
New file @@ -0,0 +1,69 @@ package com.ard.web.controller.system; import com.alibaba.fastjson2.JSONObject; import com.ard.authorize.service.AuthorizeService; import com.ard.common.annotation.Anonymous; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; @Api(tags = "授权管理接口") @RestController @RequestMapping("Authorization") @Anonymous public class AuthorizationController { @Resource AuthorizeService authorizeService; //生成临时授权只有一天 @PostMapping("/makeTempLicense") public JSONObject makeTempLicense() { JSONObject jsonObject = authorizeService.makeTempLicense(); return jsonObject; } //获取机器码 @ApiOperation("获取机器码") @PostMapping("/getMachineCode") public JSONObject getMachineCode() { JSONObject jsonObject = authorizeService.getMachineCode(); return jsonObject; } //上传授权文件 @ApiOperation("上传授权文件") @PostMapping(value = "/uploadLicenseFile") public JSONObject uploadLicense(@RequestPart MultipartFile file) { JSONObject jsonObject = authorizeService.uploadLicense(file); return jsonObject; } //验证授权文件是否到期 @ApiOperation("验证授权文件是否到期") @PostMapping(value = "/verifyAuthorization") public JSONObject verifyAuthorization() { JSONObject data = authorizeService.verifyAuthorization();//解析授权文件 return data; } //授权信息 @ApiOperation("授权信息") @GetMapping(value = "/getAuthorizationInfo") public JSONObject getAuthorizationInfo() { JSONObject data = authorizeService.getAuthorizationInfo();//解析授权文件 return data; } //加密 @PostMapping(value = "/getLicense") public String getLicense(@RequestBody String data) { String EncryptedStr = authorizeService.encryption(data); return EncryptedStr; } //解密 @PostMapping(value = "/parsLicense") public String parsLicense(@RequestBody String data) { String DecryptStr = authorizeService.decryption(data); return DecryptStr; } } ard-common/src/main/java/com/ard/common/constant/CacheConstants.java
@@ -41,4 +41,9 @@ * 登录账户密码错误次数 redis key */ public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; /** * 授权使用机器码 redis key */ public static final String AUTH_CONFIG_KEY = "auth_config:"; } ard-system/pom.xml
@@ -22,6 +22,11 @@ <groupId>com.ard</groupId> <artifactId>ard-common</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> </dependencies> ard-system/src/main/java/com/ard/authorize/common/AuthorizeUtil.java
New file @@ -0,0 +1,322 @@ package com.ard.authorize.common; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Hex; import org.apache.commons.compress.utils.IOUtils; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import java.io.*; import java.net.InetAddress; import java.net.NetworkInterface; import java.util.*; @Slf4j(topic="authorize") public class AuthorizeUtil { public static String MachineCode=""; private static String confusionString = "TczYTMY2MzII32MVjZjgjMzYWmQwM5z"; private static String confusionString2 = "0ZDMwM2UxYTFmZmRZWZkMkODUxNGYzM"; private static String confusionString3 = "MxYzY2ZDUYzN5MAOWViNWQ3YzOTRke9"; private static String confusionString4 = "f15a5M0MjNmExNlNkNDQzWI3MTE1NTN"; private static String getKeyStr(String keyStr) { return Md5Utils.hash(keyStr); } public static void main(String[] args) { AuthorizeUtil ss = new AuthorizeUtil(); log.debug("sysStr " + ss.parsLicense()); log.debug("MachineCode " + ss.getMachineCode()); log.debug("CPUCode " + ss.getCPUCode()); //String codeString=ss.parsLicense("b1db709f19d9769e536e2e29888e38b2"); //System.out.println(codeString); //ss.makeTempLicense(); //System.out.println("get "+ss.parsLicense()); //ss.writeFile("22"); /* String str = "{\"systemAuthorizeDate\":\"20190404240000\",\"meteorologicalDeviceType\":\"1,2\",\"meteorologicalDeviceNum\":\"999\",\"screenDeviceType\":\"1,2,3\",\"screenDeviceNum\":\"999\",\"captureDeviceType\":\"1,2,3,4\",\"captureDeviceNum\":\"999\"}"; str = "{\"systemAuthorizeDate\":\"20180721015732\",\"meteorologicalDeviceType\":\"1,2\",\"meteorologicalDeviceNum\":\"10\",\"screenDeviceType\":\"1,2,3\",\"screenDeviceNum\":\"10\",\"captureDeviceType\":\"1,2,3,4\",\"captureDeviceNum\":\"10\"}"; //System.out.println(ss.encode(key).replace("9", "QQQ999QQQ999QQQ")); System.out.println(str);*/ String key = ss.getMachineCode(); String stringcodeString = "MGNiYTEwMDNhZTBmNTI2MmUzNGI1ZWNjYmFmZGY3ZDY3ZDU4MDNkMGQ2NTFkYmE4Mjc0NTZjNTQxMzMwZWNmYTkxNDJkYWNjODNiMGYyOTU3MDhlY2QzMDJhMjFjM2VjMmU0M2UyYmFhNzIzNDc5YjMzYjU0YmQzOTVmM2ZmZjE4MjZjYTZlMGQ3ZGM4MjNkY2ZiMWQ0MDkyMDk4ZTYxOTA1ZTM5ZmJkZWI2MTQwNTllNDY1YWQwYTg1OThkNWJkMDljMjRiY2Q2ZTA5NTQzYjYzNWNhNWJhZDZjYTAyMDFmMTYwNzVkNzI2MGEyMThiZDc2MTc0YjRkYjllNjdkZDRjY2ExMTgwYWFhZGU5YzlmY2Y0ZmI0N2Q5N2Q4NjNiNDYxMDAwMzQwNmE3OWM1ODc5YzVjOGYwYmIxMDQ1YjM5NWJkYTk5MjJkOWE1NTRlMDJiYWNlOTE2NmIxYmNiYTZjMTZjZjVhNzMwY2M0NzU1NDhlMGUwOTQ5NzQ4ZWJiMDU4ODcxZmQyYjk4ZWMyNWU2N2RlOWY0ZGFhZGU3MmVmZmJiMGQxNzEzNGZjODZkZmFlYjkxOTU2OTliNmMwMzJkNmU3YmZmMzIzODRmM2UyYzViZTY4NWY5NDY1YjlhODIyZjFiMGQ1NzhlODJjYmNkYzA1YWNhYTg2ODZlMzY2OGQ1ZWRlNmM5YzRiN2RhYTFjZDY0NWQ5ZGMxYmU0YTM1N2U2NDA1NDQxYmVjMWEwM2M2NTQzMTM1YjJjYzY2YjJiMmZkZjNlZWYzZTY5YTQ3YWVlNjhiZTNjMTliMmEyZGZhZWY0NDRmYWEwZDc1MDMxODEyNGE1ZjFjMDZmZGY3MTQzZGYxNDdmYjRmMDdkZTBiYThjYmJlNmFhM2Y1MTk2NTE4MjgwNjYyYzAxMWYyOTNkOWYyYzdlYzQ3Mzc1YTVjZWFiZjdjZGJhYjAxZGRkZWQ5OWUwYTJkNzE1NDBiMjU0MDlmMTQzMThkNDMzNGQyZjNhMjllNDRmYzdlZjA3ZjhhYmE2ZTJiNDZlNjcxNzJhMDJhMjJjZDE3YTZkNTE0MzI2MTkxZjkxMGUyZmE4MGE5ZTFlNjQxZDk3ZDcyZDliYTNjMDI3YjZlYzk3MDIwMDY1YTJhYjEyNTg0"; System.out.println("ok " + ss.parsLicense(key, stringcodeString)); //System.out.println(ss.parsLicense("OWUzYTIxYWI4MWQxZGJlMmYxNDEyY2Y2YWU4NWQzZGFmZjZlZWUwNTMzYmY2ZWI4NWM5ZDFkZTIxMDAwODA5NDJhZGU5NDQ4NmI0MjY3ZmRhMWI0ZjYwZWIxYzU4ZjgzYjNhOTMyZjJiOTZiZjk4ZjY2Y2M0MDg0YjAyMjYwYzhlZjc2YjYwZTJiODQ4MjJmY2Y2ZWRhNTAxM2Q4Zjk0YmZkMGViYjdkYzBkMThjMjRhNDRmZWI3ZTQ2YjM4ZDQ2MjQ1YmQzOTYyYmJhYmRjYzg2Njc5NWQ4MTEyZTEyNjFjMmY3ZjQ1NDY5Y2VmOTliM2I5YzdkMmQxYjYzNWJlMzRjMzZhY2VlYTE0MjdlMjA2NWU3YWY5NGZmZjFjZGM1ODVkNzZlNDVlMmZlNjBlN2Q4ZDMwNThiMDU2MzYyMTE1OTMxYzg2Y2E1MmVjN2Y0YzhiYTBiZGNlYzQ3MjMzYWI4MWEzYzZhZDhkYjQzYTk1YTFiMGRkODJlOGYzNjQzNDE0MzNkYzNhNjA1ZjExN2Y3YTZhODcyNTA3ZTRkYjRjY2FlM2IwMDU4MTg4Y2FhMzA5YjdiN2QzOGQ2MGU3MTU5MzFjODZjYTUyZWM3ZjRjOGJhMGJkY2VjNDcyMzNhNTM3NDZlN2ZlOGFiZWM5OWY2YzhlMTg3NTc0OWEzYmM=")); //System.out.println(ss.parsLicense()); //System.out.println(ss.parsLicense("ZjRmYjNhYzdiY2Q1NGFjZjc0NWNiNzg1MGMzYTg2YjRzMXkybjNqNG81bjZlN3M4ZWRiN2NzMXkybjNqNG81bjZlN3M4ZmU2YXMxeTJuM2o0bzVuNmU3czg1MDI0ZDI1NDM0ODJjOGQ3N2E3NDRjM2NjYTg3ZHMxeTJuM2o0bzVuNmU3czhmYnMxeTJuM2o0bzVuNmU3czhlYmNkZTQ1czF5Mm4zajRvNW42ZTdzOGU1YjNzMXkybjNqNG81bjZlN3M4YTRkYjcyMTc1ZmZlNHMxeTJuM2o0bzVuNmU3czhzMXkybjNqNG81bjZlN3M4OGJiYWNjZDM3Y2NlZDQwMTBzMXkybjNqNG81bjZlN3M4MzJzMXkybjNqNG81bjZlN3M4ZDBhZjM3NmQ1YnMxeTJuM2o0bzVuNmU3czg1YTMwNmI4ODdkNWRjYmFjZHMxeTJuM2o0bzVuNmU3czg2YzEwZThjMTMxNjE0YTU2MzJlNjdzMXkybjNqNG81bjZlN3M4OGI3YWMwNThhMmNzMXkybjNqNG81bjZlN3M4YWRkNzAyNzU1NzBhYjVlN2M2YmVlMXMxeTJuM2o0bzVuNmU3czhiZWNiYzg3NHMxeTJuM2o0bzVuNmU3czg2ZTBmMTM1NTRhOGMxZjRlYjA0ZmJkZmM1NzU0NDMzMjBkNjRlMjQxN3MxeTJuM2o0bzVuNmU3czgwM2E0YjBlYTAwM2Y1NDNlMjhzMXkybjNqNG81bjZlN3M4YXMxeTJuM2o0bzVuNmU3czhiMWY2MTM0YWFiNDBzMXkybjNqNG81bjZlN3M4NTFiYmYxNXMxeTJuM2o0bzVuNmU3czg4NWZhYThhN3MxeTJuM2o0bzVuNmU3czgyMzIyNjQxNTc1YXMxeTJuM2o0bzVuNmU3czgzMTJkZThmM2FmNjQ4MjQwYzYxMTdhYmVzMXkybjNqNG81bjZlN3M4MjFlM3MxeTJuM2o0bzVuNmU3czhhMWVlMTQxczF5Mm4zajRvNW42ZTdzODZlZGJlNjA3YWE2OGE0MmFkNDVmMjE3NzY4NDhlMWM1ZDVkZTNjYzIxNmEyNmUwMzFkODY4czF5Mm4zajRvNW42ZTdzODZmczF5Mm4zajRvNW42ZTdzODA4NTI0YmUzczF5Mm4zajRvNW42ZTdzOGVjM2Y0NmI3czF5Mm4zajRvNW42ZTdzODYyM2ZkYjVhMTY1ZTc0MzJmczF5Mm4zajRvNW42ZTdzODFmZWY3ODc2ZTE4NjQ3ZjY4YjFzMXkybjNqNG81bjZlN3M4NmRjMTBiczF5Mm4zajRvNW42ZTdzOGU2MDE3ZDQ1MzFmZWUzczF5Mm4zajRvNW42ZTdzOGMzczF5Mm4zajRvNW42ZTdzOGNzMXkybjNqNG81bjZlN3M4YjdmODMyMjRlczF5Mm4zajRvNW42ZTdzOHMxeTJuM2o0bzVuNmU3czg2YjBmNTdjYjVkNmIzNzU3NTBkMGI3MjdmNDM2YnMxeTJuM2o0bzVuNmU3czg4ZGRjM2FhMmM2ODFlNjcwMGQ0MmExNDdmNTdhZDEyMGU4ZDFmN2FlMDFmNmE1ZmUwczF5Mm4zajRvNW42ZTdzODgzY2IwNGZiYzg4NGQzZTZkZGYyMTRmZThlZTIzZDA0ZmU4ZTNlYjBiZDBkMzhzMXkybjNqNG81bjZlN3M4NmZzMXkybjNqNG81bjZlN3M4MDg1MjRiZTNzMXkybjNqNG81bjZlN3M4ZWMzZjQ2YjdzMXkybjNqNG81bjZlN3M4NjIzZmRiNWExMGM1YTQ2YWUwNjNzMXkybjNqNG81bjZlN3M4MGNzMXkybjNqNG81bjZlN3M4Y2QyYWU4MjU4MWYwZWQ1MTc=")); } //获取到授权信息生成-加密信息返回 public static String getLicense(String key, String str) { String aString = str.replaceAll("Authorize", confusionString); String bString = encodeAES(getKeyStr(key), aString); String cString = encode64(bString).replaceAll("==", confusionString3).replaceAll("=", confusionString4).replaceAll("4M", confusionString2); return cString; } //获取到加密信息和机器码-解密信息返回 public static String parsLicense(String key, String str) { try { str = str.replaceAll(confusionString3, "==").replaceAll(confusionString4, "=").replaceAll(confusionString2, "4M"); String pString = decode64(str); return decodeAES(getKeyStr(key), pString).replaceAll(confusionString, "Authorize"); } catch (Exception ex) { } return null; } public static String getMachineCode() { StringBuffer sb = new StringBuffer(); try { InetAddress ia = InetAddress.getLocalHost(); log.debug("IP:"+ia.getHostAddress()); NetworkInterface byInetAddress = NetworkInterface.getByInetAddress(ia); log.debug("网卡:"+byInetAddress.getName()); byte[] mac = byInetAddress.getHardwareAddress(); for (int i = 0; i < mac.length; i++) { if (i != 0) { sb.append("-"); } int temp = mac[i] & 0xff;//字节转换为整数 String str = Integer.toHexString(temp); if (str.length() == 1) { sb.append("0" + str); } else { sb.append(str); } } log.debug("mac:"+sb.toString().toUpperCase()); } catch (Exception e) { log.error("获取机器码异常:"+e.getMessage()); } String code = Md5Utils.hash(sb.toString().toUpperCase()); log.debug("机器码:"+code); return code; } public static String getCPUCode() { String serial = null; try { Process process = Runtime.getRuntime().exec(new String[]{"wmic", "cpu", "get", "ProcessorId"}); process.getOutputStream().close(); Scanner sc = new Scanner(process.getInputStream()); String property = sc.next(); serial = sc.next(); serial = Md5Utils.hash(serial); //System.out.println(property + ": " + serial); } catch (IOException e) { serial = null; } if (serial == null) { serial = getMachineCode(); } return serial; } //制作临时授权 public static String makeTempLicense(String FilePath) { String tempLicenseDate = ""; String str = readToString(FilePath); if (str.equals("")) {//没有授权文件 Date date = new Date();//取时间 Calendar calendar = new GregorianCalendar(); calendar.setTime(date); calendar.add(Calendar.DATE, 1);//把日期往后增加一天.正数往后推,负数往前推 date = calendar.getTime(); //这个时间就是日期往后推一天的结果 tempLicenseDate = (new java.text.SimpleDateFormat("yyyyMMddhhmmss")).format(date); String machineCode = getMachineCode(); String tempLicense = "{\"machineCode\":\"" + machineCode + "\",\"systemAuthorizeDate\":\"" + tempLicenseDate + "\"}"; writeFile(FilePath, getLicense(getMachineCode(), tempLicense)); } return tempLicenseDate; } public static String parsLicense(String machineCode) { String str = readToString("D:\\synjones.env\\license.cpy"); String returnStr = ""; //System.out.println("readfile "+str); if (str.equals("")) {//没有授权文件 returnStr = "null"; } else { try { returnStr = parsLicense(machineCode, str); } catch (Exception e) { returnStr = "error"; } } return returnStr; } public static String parsLicense() { String authorizeCode = parsLicense(getMachineCode()); if (authorizeCode.equals("error")) { authorizeCode = parsLicense(getCPUCode()); } return authorizeCode; } //base64编码 public static String encode64(String src) { byte[] encodeBytes = Base64.getEncoder().encode(src.getBytes()); return new String(encodeBytes); } //base64解码 public static String decode64(String src) { byte[] decodeBytes = Base64.getDecoder().decode(src.getBytes()); return new String(decodeBytes); } //AES加密 public static String encodeAES(String key, String src) { try { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(128);// size SecretKey secretKey = keyGenerator.generateKey(); // byte[] keyBytes = HexBin.decode(key); byte[] keyBytes = DatatypeConverter.parseHexBinary(key); SecretKey generateKey = new SecretKeySpec(keyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, generateKey); byte[] resultBytes = cipher.doFinal(src.getBytes()); return Hex.encodeHexString(resultBytes); } catch (Exception e) { e.printStackTrace(); } return null; } public static void writeFile(String FilePath, String content) { String FileName = FilePath.substring(FilePath.lastIndexOf("\\") + 1); String FileDir = FilePath.substring(0, FilePath.lastIndexOf("\\") + 1); FileOutputStream fileWriter; OutputStreamWriter writer = null; try { File outDir = new File(FileDir); if (!outDir.exists() && !outDir.isDirectory()) { outDir.mkdir(); } String file = FilePath; String charSet = "UTF-8"; //写字符转换成字节流 fileWriter = new FileOutputStream(file); writer = new OutputStreamWriter(fileWriter, charSet); writer.write(content); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } finally { try { writer.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static String readToString(String fileName) { String encoding = "UTF-8"; File file = new File(fileName); Long filelength = file.length(); byte[] filecontent = new byte[filelength.intValue()]; try { FileInputStream in = new FileInputStream(file); in.read(filecontent); in.close(); } catch (FileNotFoundException e) { return ""; } catch (IOException e) { return ""; } try { return new String(filecontent, encoding); } catch (UnsupportedEncodingException e) { System.err.println("The OS does not support " + encoding); e.printStackTrace(); return ""; } } //读取文件中的字符串 public static String readFile(File file) { BufferedReader reader = null; try { //用流读取文件 reader = new BufferedReader(new FileReader(file)); String line; StringBuffer content = new StringBuffer(); // 读取想定文件 while ((line = reader.readLine()) != null) { content.append(line); } return content.toString(); } catch (IOException e) { return null; } finally { if (reader != null) { IOUtils.closeQuietly(reader); } } } //AES解密 public static String decodeAES(String key, String src) { try { // byte[] keyBytes = HexBin.decode(key); byte[] keyBytes = DatatypeConverter.parseHexBinary(key); SecretKey generateKey = new SecretKeySpec(keyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, generateKey); byte[] result = Hex.decodeHex(src.toCharArray()); return new String(cipher.doFinal(result)); } catch (Exception e) { //e.printStackTrace(); } return null; } public static String encode(String key, String src) { try { KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede"); keyGenerator.init(168);// size SecretKey secretKey = keyGenerator.generateKey(); // byte[] keyBytes = HexBin.decode(key); byte[] keyBytes = DatatypeConverter.parseHexBinary(key); DESedeKeySpec desKeySpec = new DESedeKeySpec(keyBytes); SecretKeyFactory secretKeyFactory = SecretKeyFactory .getInstance("DESede"); SecretKey generateKey = secretKeyFactory.generateSecret(desKeySpec); Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, generateKey); byte[] resultBytes = cipher.doFinal(src.getBytes()); return Hex.encodeHexString(resultBytes); } catch (Exception e) { e.printStackTrace(); } return null; } } ard-system/src/main/java/com/ard/authorize/common/DateTimeUtil.java
New file @@ -0,0 +1,393 @@ package com.ard.authorize.common; import org.apache.commons.lang3.time.DateUtils; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * 日期时间工具类 * @author wq * @version 1.0 */ public class DateTimeUtil extends DateUtils { // 以毫秒表示的时间 private static final long DAY_IN_MILLIS = 24 * 3600 * 1000; private static final long HOUR_IN_MILLIS = 3600 * 1000; private static final long MINUTE_IN_MILLIS = 60 * 1000; private static final long SECOND_IN_MILLIS = 1000; private static String week[] = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }; /** * 用指定参数抽取时间日期部分 * <br/>例如getDateSplit(System.currentTimeMillis()),"y") 为取得当前的年份 * @param date java.util.Date类型时间 * @param interval 可选值: * <br/>y:年<br/>M:月<br/>d/dm:日<br/>dy:参数日期所代表的时间的已过的天数 * <br/>h:12制小时<br/>H:24制小时<br/>m:分 * <br/>s:秒<br/>S:毫秒<br/>w:星期 * <br/>wim:参数日期所代表的月已经过的星期数 * <br/>wm:参数日期所代表的月的星期数 * <br/>wy:参数日期所代表的年的第几周 * @return 格式化好的时间 */ public static int getDateExtract(Date date, String interval) { Calendar c = Calendar.getInstance(); c.setTime(date); if (interval.equalsIgnoreCase("y")) return c.get(Calendar.YEAR); if (interval.equals("M")) return c.get(Calendar.MONTH); if (interval.equalsIgnoreCase("d")) return c.get(Calendar.DATE); if (interval.equalsIgnoreCase("dm")) return c.get(Calendar.DAY_OF_MONTH); if (interval.equalsIgnoreCase("dy")) return c.get(Calendar.DAY_OF_YEAR); if (interval.equals("h")) return c.get(Calendar.HOUR); if (interval.equals("H")) return c.get(Calendar.HOUR_OF_DAY); if (interval.equals("m")) return c.get(Calendar.MINUTE); if (interval.equals("s")) return c.get(Calendar.SECOND); if (interval.equals("S")) return c.get(Calendar.MILLISECOND); if (interval.equalsIgnoreCase("w")) return c.get(Calendar.DAY_OF_WEEK); if (interval.equalsIgnoreCase("wim")) return c.get(Calendar.DAY_OF_WEEK_IN_MONTH); if (interval.equalsIgnoreCase("wm")) return c.get(Calendar.WEEK_OF_MONTH); if (interval.equalsIgnoreCase("wy")) return c.get(Calendar.WEEK_OF_YEAR); else return -1; } /** * 用指定参数抽取时间日期部分 * @param dateStr String类型日期时间 * @param format 日期时间格式 * @param interval 可选值: * <br/>y:年<br/>M:月<br/>d/dm:日<br/>dy:参数日期所代表的时间的已过的天数 * <br/>h:12制小时<br/>H:24制小时<br/>m:分 * <br/>s:秒<br/>S:毫秒<br/>w:星期 * <br/>wim:参数日期所代表的月已经过的星期数 * <br/>wm:参数日期所代表的月的星期数 * <br/>wy:参数日期所代表的年的第几周 * @return 格式化好的时间 * @throws ParseException */ public static int getDateExtract(String dateStr, String format, String interval) throws ParseException { SimpleDateFormat sformat = new SimpleDateFormat(format); Date date = sformat.parse(dateStr); return getDateExtract(date, interval); } /** * @param value 时间 * @return yyyy-MM-dd HH:mm:ss格式的时间字符串 */ public static String getSpecifyDateTime(long value) { return getFormatDateTime(new Date(value), "yyyy-MM-dd HH:mm:ss"); } /** * 转换一个Long型到Date类型 * @param value 时间 * @return java.util.Date */ public static Date getDateTime(long value) { Calendar c = Calendar.getInstance(); c.setTimeInMillis(value); return c.getTime(); } /** * 取得当前星期 * @return 字符串 */ public static String getCurrentWeek() { return week[getDateExtract(new Date(), "w") - 1]; } /** * 从给出的时间计算星期 * @param date 日期 * @return 字符串 */ public static String getWeek(Date date) { return week[getDateExtract(date, "w") - 1]; } /** * 从给出的时间计算星期 * @param dateStr 日期字符串 * @param format 日期格式 * @return 字符串 */ public static String getWeek(String dateStr, String format) throws ParseException { return week[getDateExtract(dateStr, format, "w") - 1]; } /** * 用指定格式,格式一个日期 * @param date * @param format * @return 字符串 */ public static String getFormatDateTime(Date date, String format) { return (new SimpleDateFormat(format)).format(date); } /** * string类型时间转为java.util.Date类型时间 yyyy-MM-dd 无时分秒 * @param strDate * @return * @throws ParseException */ public static Date changeStringToDate(String strDate) throws ParseException { if (strDate == null || strDate.equals("")) return null; else return DateFormat.getDateInstance(DateFormat.DEFAULT).parse(strDate); } /** * 去得紧凑型日期 例如yyyyMMdd * @param data 型如yyyy-MM-dd * @return 字符串 */ public static String getCompactDate(String data) { if (data == null || data.length() < 10) { return ""; } else { data = (new StringBuilder(String.valueOf(data.substring(0, 4)))).append(data.substring(5, 7)).append(data.substring(8, 10)).toString(); return data; } } /** * 得到Long型时间从给定yyyy-MM-dd HH:mm:ss型字符串 * @param strDate * @return Long型时间 * @throws ParseException */ public static long getLongDate(String strDate) throws ParseException { DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = format.parse(strDate); Calendar c = Calendar.getInstance(); c.setTime(date); Long l = c.getTimeInMillis(); return l; } /** * 格式化Long类型时间 * @param longDate Long类型时间 * @param format 时间格式 * @return java.util.Date * @throws ParseException */ public static Date getFormatDate(long longDate, String format) throws ParseException { DateFormat dformat = new SimpleDateFormat(format); Calendar c = Calendar.getInstance(); c.setTimeInMillis(longDate); String dt = dformat.format(c.getTime()); return dformat.parse(dt); } /** * 格式化String类型时间 * @param strDate String类型时间 * @param format 时间格式 * @return java.util.Date * @throws ParseException */ public static Date getFormatDate(String strDate, String format) throws ParseException { DateFormat dformat = new SimpleDateFormat(format); return dformat.parse(strDate); } /** *将字符串格式yyyyMMdd的字符串转为日期,格式"yyyy-MM-dd" * * @param date 日期字符串 * @return 返回格式化的日期 * @throws ParseException 分析时意外地出现了错误异常 */ public static String strToDateFormat(String date) throws ParseException { SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); formatter.setLenient(false); Date newDate= formatter.parse(date); formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return formatter.format(newDate); } /** * 格式化Date类型时间 * @param date Date类型时间 * @param format 时间格式 * @return java.util.Date * @throws ParseException */ public static Date getFormatDate(Date date, String format) throws ParseException { DateFormat dformat = new SimpleDateFormat(format); String dt = dformat.format(date); return dformat.parse(dt); } /** * 用指定格式格式化当前时间 * * @param format * <br/>时间格式 例yyyy-MM-dd HH:mm:ss * <br/>"yyyy.MM.dd G 'at' HH:mm:ss z" 2001.07.04 AD at 12:08:56 PDT * <br/>"EEE, MMM d, ''yy" 星期五, 三月 9, '12 * <br/>"h:mm a" 12:08 PM * <br/>GGG hh:mm aaa" 02001.July.04 AD 12:08 PM * <br/>"EEE, d MMM yyyy HH:mm:ss Z" Wed, 4 Jul 2001 12:08:56 -0700 * <br/>"yyMMddHHmmssZ" 010704120856-0700 * <br/>"yyyy-MM-dd'T'HH:mm:ss.SSSZ" 2001-07-04T12:08:56.235-0700 * @return 格式化的时间 */ public static String getCurrentDate(String format) { return getFormatDateTime(new Date(), format); } /** * 反回一个Long型的当前时间 * @return <Long> 当前时间 */ public static Long getCurrentLongDate(){ return new Date().getTime(); } /** * 取得yyyy-MM-dd格式的当前时间 * @return 格式化的时间 */ public static String getCurrentDate() { return getCurrentDate("yyyy-MM-dd"); } // //////////////////////////////////////////////////////////////////////////// // dateDiff // 计算两个日期之间的差值 // //////////////////////////////////////////////////////////////////////////// /** * 计算两个时间之间的差值,根据标志的不同而不同 * * @param flag * 计算标志,表示按照年/月/日/时/分/秒等计算 * @param calSrc * 减数 * @param calDes * 被减数 * @return 两个日期之间的差值 */ public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) { long millisDiff = calSrc.getTime().getTime() - calDes.getTime().getTime(); if (flag == 'y') { return (calSrc.get(calSrc.YEAR) - calDes.get(calDes.YEAR)); } if (flag == 'd') { return (int) (millisDiff / DAY_IN_MILLIS); } if (flag == 'h') { return (int) (millisDiff / HOUR_IN_MILLIS); } if (flag == 'm') { return (int) (millisDiff / MINUTE_IN_MILLIS); } if (flag == 's') { return (int) (millisDiff / SECOND_IN_MILLIS); } return 0; } /** * 传入时间加上或减去指定的时间间隔 * @param date * @param interval * @return */ public static Date addDay(Date date, int interval) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.DAY_OF_MONTH, interval); return cal.getTime(); } /** * 传入时间 加上或减去 小时 * @param date * @param interval * @return */ public static Date addHour(Date date, int interval){ Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.HOUR_OF_DAY, interval); return cal.getTime(); } /* * 传入时间 加上或减去 分钟 */ public static Date addMinute(Date date, int interval){ Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.MINUTE, interval); return cal.getTime(); } /* * 传入时间 加上或减去 秒 */ public static Date addSecond(Date date, int interval){ Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.SECOND, interval); return cal.getTime(); } // public static void main(String args[]) throws ParseException // { // System.out.println(getFormatDateTime(addDay(new Date(),-3), "yyyy-MM-dd HH:mm:ss")); // } } ard-system/src/main/java/com/ard/authorize/common/Md5Utils.java
New file @@ -0,0 +1,46 @@ package com.ard.authorize.common; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.security.MessageDigest; public class Md5Utils { private static final Logger LOGGER = LoggerFactory.getLogger(Md5Utils.class); private static byte[] md5(String s) { MessageDigest algorithm; try { algorithm = MessageDigest.getInstance("MD5"); algorithm.reset(); algorithm.update(s.getBytes("UTF-8")); byte[] messageDigest = algorithm.digest(); return messageDigest; } catch (Exception e) { LOGGER.error("MD5 Error...", e); } return null; } private static final String toHex(byte hash[]) { if (hash == null) { return null; } StringBuffer buf = new StringBuffer(hash.length * 2); int i; for (i = 0; i < hash.length; i++) { if ((hash[i] & 0xff) < 0x10) { buf.append("0"); } buf.append(Long.toString(hash[i] & 0xff, 16)); } return buf.toString(); } public static String hash(String s) { try { return new String(toHex(md5(s)).getBytes("UTF-8"), "UTF-8"); } catch (Exception e) { LOGGER.error("not supported charset...{}", e); return s; } } } ard-system/src/main/java/com/ard/authorize/domain/AuthorizeInfo.java
New file @@ -0,0 +1,27 @@ package com.ard.authorize.domain; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @ClassName AuthorizeInfo * @Description: 申请授权信息实体类 * @Author 刘苏义 * @Date 2022/11/30 17:18 * @Version 1.0 */ @Data @AllArgsConstructor @NoArgsConstructor public class AuthorizeInfo { //授权日期 private String systemAuthorizeDate; //机器码 private String machineCode; //无人机授权数量 private Integer droneNum; //机场授权数量 private Integer dockNum; } ard-system/src/main/java/com/ard/authorize/domain/ParsLicenseInfo.java
New file @@ -0,0 +1,22 @@ package com.ard.authorize.domain; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @ClassName ParsLicenseInfo * @Description: 申请解密信息实体类 * @Author 刘苏义 * @Date 2022/11/30 17:18 * @Version 1.0 */ @Data @NoArgsConstructor @AllArgsConstructor public class ParsLicenseInfo { public String machineCode;//机器码 public String EncryptedStr;//加密串 } ard-system/src/main/java/com/ard/authorize/service/AuthorizeService.java
New file @@ -0,0 +1,16 @@ package com.ard.authorize.service; import com.alibaba.fastjson2.JSONObject; import org.springframework.web.multipart.MultipartFile; public interface AuthorizeService { JSONObject verifyAuthorization();//验证本地授权 JSONObject getAuthorizationInfo();//获取授权信息 JSONObject makeTempLicense();//制作临时授权 JSONObject getMachineCode();//获取机器码 JSONObject uploadLicense(MultipartFile file);//上传授权文件 String encryption(String data);//加密 String decryption(String data);//解密 } ard-system/src/main/java/com/ard/authorize/service/AuthorizeServiceImpl.java
New file @@ -0,0 +1,331 @@ package com.ard.authorize.service; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.ard.authorize.common.AuthorizeUtil; import com.ard.authorize.common.DateTimeUtil; import com.ard.authorize.domain.AuthorizeInfo; import com.ard.authorize.domain.ParsLicenseInfo; import com.ard.common.constant.CacheConstants; import com.ard.common.core.redis.RedisCache; import lombok.extern.slf4j.Slf4j; import org.apache.commons.compress.utils.IOUtils; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.text.ParseException; @Service @Slf4j(topic = "Authorize") public class AuthorizeServiceImpl implements AuthorizeService { @Resource private RedisCache redisCache; @PostConstruct public void init() { log.debug("尝试获取获取机器码"); AuthorizeUtil.MachineCode = AuthorizeUtil.getMachineCode(); log.debug("机器码获取成功:" + AuthorizeUtil.MachineCode); redisCache.setCacheObject(getCacheKey("MachineCode"), AuthorizeUtil.MachineCode); } /** * 系统授权时间判断 * * @return boolean */ public boolean isExpired(AuthorizeInfo Info) { try { if (Info != null) { String dateStr = Info.getSystemAuthorizeDate(); dateStr = DateTimeUtil.strToDateFormat(dateStr); //授权到期时间 long dates = DateTimeUtil.getLongDate(dateStr); long currentTime = DateTimeUtil.getCurrentLongDate(); //授权是否到期 if (dates >= currentTime) { return true; } } } catch (ParseException e) { log.error("系统授权时间判断异常:" + e.getMessage()); } return false; } /** * 解析授权文件 * * @return AuthorizeInfo */ public AuthorizeInfo parseFiles(File file) { BufferedReader reader = null; try { //用流读取文件 reader = new BufferedReader(new FileReader(file)); String line; StringBuffer content = new StringBuffer(); // 读取想定文件 while ((line = reader.readLine()) != null) { content.append(line); } String MachineCode = AuthorizeUtil.MachineCode; String str = AuthorizeUtil.parsLicense(MachineCode, content.toString()); if (str != null) { AuthorizeInfo info = JSONObject.parseObject(str, AuthorizeInfo.class); return info; } } catch (IOException e) { log.error("解析授权文件异常:" + e.getMessage()); return null; } finally { if (reader != null) { IOUtils.closeQuietly(reader); } } return null; } /** * 验证授权 * * @return JSONObject */ @Override public JSONObject verifyAuthorization() { try { JSONObject data = new JSONObject(); String savedDir = System.getProperty("user.dir") + "\\ardLicense"; File dir = new File(savedDir); if (!dir.exists()) { //如果不存在 boolean dr = dir.mkdirs(); //创建目录 } //从缓存中获取最后一次验证授权的时间 Object auth_time = redisCache.getCacheObject(getCacheKey("AuthTime")); if (auth_time != null) { long lasttime = Long.parseLong(auth_time.toString()); long currentTime = DateTimeUtil.getCurrentLongDate(); if (currentTime <= lasttime) { data.put("Type", "error"); data.put("Message", "系统时间异常"); return data; } } File LicenseFile = new File(savedDir + "/license.cpy");//获取授权文件 if (LicenseFile.exists()) { AuthorizeInfo info = parseFiles(LicenseFile);//解析授权文件 if (info != null) { if (isExpired(info)) { data.put("Type", "normal"); data.put("Message", info.getSystemAuthorizeDate()); } else { data.put("Type", "expired"); data.put("Message", info.getSystemAuthorizeDate()); } } else { data.put("Type", "mismatch"); data.put("Message", "License mismatch"); } } else { data.put("Type", "mismatch"); data.put("Message", "License mismatch"); } //验证结束,写入最后一次验证的时间到缓存 redisCache.setCacheObject(getCacheKey("AuthTime"), DateTimeUtil.getCurrentLongDate().toString()); return data; } catch (Exception ex) { log.error("验证授权异常:" + ex.getMessage()); return null; } } /** * 获取授权信息 * * @return JSONObject */ @Override public JSONObject getAuthorizationInfo() { try { JSONObject data = new JSONObject(); String savedDir = System.getProperty("user.dir") + "\\ardLicense"; File dir = new File(savedDir); if (!dir.exists()) { //如果不存在 boolean dr = dir.mkdirs(); //创建目录 } //从缓存中获取最后一次验证授权的时间 Object auth_time = redisCache.getCacheObject(getCacheKey("AuthTime")); if (auth_time != null) { long lasttime = Long.parseLong(auth_time.toString()); long currentTime = DateTimeUtil.getCurrentLongDate(); if (currentTime <= lasttime) { data.put("Type", "error"); data.put("Message", "系统时间异常"); return data; } } File LicenseFile = new File(savedDir + "/license.cpy");//获取授权文件 if (LicenseFile.exists()) { AuthorizeInfo info = parseFiles(LicenseFile);//解析授权文件 if (info != null) { if (isExpired(info)) { data.put("Type", "normal"); data.put("Message", info.getSystemAuthorizeDate()); data.put("droneNum", info.getDroneNum()); data.put("dockNum", info.getDockNum()); } else { data.put("Type", "expired"); data.put("Message", info.getSystemAuthorizeDate()); } } else { data.put("Type", "mismatch"); data.put("Message", "License mismatch"); } } else { data.put("Type", "mismatch"); data.put("Message", "License mismatch"); } //验证结束,写入最后一次验证的时间到缓存 redisCache.setCacheObject(getCacheKey("AuthTime"), DateTimeUtil.getCurrentLongDate().toString()); return data; } catch (Exception ex) { log.error("验证授权异常:" + ex.getMessage()); return null; } } /** * 制作临时授权 * * @return JSONObject */ @Override public JSONObject makeTempLicense() { String savedDir = System.getProperty("user.dir") + "\\ardLicense"; String tempLicenseDate = AuthorizeUtil.makeTempLicense(savedDir + "\\license.cpy"); JSONObject data = new JSONObject(); data.put("Type", "makeTempLicense"); data.put("Message", tempLicenseDate); return data; } /** * 获取机器码 * * @return JSONObject */ @Override public JSONObject getMachineCode() { try { String machineCode = AuthorizeUtil.getMachineCode(); AuthorizeUtil.MachineCode = machineCode; log.debug("获取到机器码:" + machineCode); JSONObject data = new JSONObject(); data.put("Type", "machineCode"); data.put("Message", machineCode); return data; } catch (Exception ex) { log.error("获取机器码异常:" + ex.getMessage()); return null; } } /** * 上传授权文件 * * @return JSONObject */ @Override public JSONObject uploadLicense(MultipartFile file) { try { String fileRealName = file.getOriginalFilename(); //获得原始文件名; String savedDir = System.getProperty("user.dir") + "\\ardLicense"; File dir = new File(savedDir); if (!dir.exists()) { //如果不存在 boolean dr = dir.mkdirs(); //创建目录 } File LicenseFile = new File(savedDir, fileRealName); try { file.transferTo(LicenseFile); //转存文件 } catch (IOException e) { e.printStackTrace(); } JSONObject data = new JSONObject(); data.put("Type", "uploadLicenseFile"); data.put("Message", "Dir:" + savedDir); return data; } catch (Exception ex) { log.error("获取机器码异常:" + ex.getMessage()); return null; } } /** * 加密授权数据 * * @return JSONObject */ @Override public String encryption(String data) { String codeString = ""; try { if (data != "") { //解析json AuthorizeInfo info = JSON.parseObject(data, AuthorizeInfo.class); String machineCode = info.getMachineCode(); if (machineCode != "" && data != "") { codeString = AuthorizeUtil.getLicense(machineCode, data); } } return codeString; } catch (Exception ex) { log.error("加密异常:" + ex.getMessage()); return codeString; } } /** * 解密授权数据 * * @return JSONObject */ @Override public String decryption(String data) { String codeString = ""; try { if (data != "") { //解析json ParsLicenseInfo rt = JSON.parseObject(data, ParsLicenseInfo.class); String machineCode = rt.getMachineCode(); String key = rt.getEncryptedStr(); codeString = AuthorizeUtil.parsLicense(machineCode, key); } } catch (Exception ex) { log.error("解密异常:" + ex.getMessage()); return codeString; } return codeString; } /** * 设置cache key * * @param configKey 参数键 * @return 缓存键key */ private String getCacheKey(String configKey) { return CacheConstants.AUTH_CONFIG_KEY + configKey; } }