package com.demo.service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.demo.common.SpecialSecret; import com.demo.constant.OSEnum; import com.demo.dao.*; import com.demo.entity.dto.DeviceReturnDto; import com.demo.entity.po.*; import com.demo.entity.vo.DeviceConfVo; import com.demo.entity.vo.DeviceIdVo; import com.demo.entity.vo.SensorVo; import com.reyun.Algorithm; import com.demo.util.DeformedBase64; import com.demo.util.RSAUtil; import com.demo.util.SecretUtil; import org.apache.commons.lang.StringEscapeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import java.util.*; @Service public class DeviceService { private final Logger logger = LoggerFactory.getLogger(DeviceService.class); private final int keyLenth = 128;//aes长度 @Autowired private SecretDao secretDao; @Autowired private DeviceInfoDao deviceInfoDao; @Autowired private DeviceConfDao deviceConfDao; @Autowired private SensorInfoDao sensorInfoDao; @Autowired private BusinDataDao businDataDao; @Autowired private HeartBeatDao heartBeatDao; // /** // * // * 获取机器的配置信息 // * @param deviceConfVo // * @return // */ // public DeviceReturnDto getDeviceConf(DeviceConfVo deviceConfVo){ // // Secret secret = getSecret(deviceConfVo.getGorganization()); // if(secret == null){ // logger.info("getDeviceConf 获取密钥失败:{}", JSONObject.toJSONString(deviceConfVo)); // return null; // } // // // 统一转成小写 // String os = deviceConfVo.getOs().toLowerCase(); // // //组装DeviceConfDataDto // List<RiskApp> riskApps = riskAppDao.findAll(os); // List<RiskDir> riskDirs = riskDirDao.findAll(os); // List<RiskFile> riskFiles = riskFileDao.findAll(os); // if(os.equals("ios")){//ios的相对安卓多出一项配置(TODO 后续补上) // // } // UpdateInfo updateInfo = updateInfoDao.findEnable(); // // DeviceConf deviceConf = deviceConfDao.findEnable(); // if(deviceConf == null){ // logger.info("getDeviceConf 配置信息找不到"); // } // // List<String> whiteApps = deviceConf != null ? Arrays.asList(deviceConf.getWhite_apps().split(",")) : null; // Integer priod = deviceConf != null ? deviceConf.getPeriod() : null; // Boolean riskFileSwitch = deviceConf != null ? deviceConf.getRisk_file_switch() : null; // DeviceConfDataDto deviceConfDataDto = new DeviceConfDataDto(riskApps, riskDirs, // riskFileSwitch, riskFiles, updateInfo, whiteApps, priod); // // String data = JSONObject.toJSONString(deviceConfDataDto); // DeviceReturnDto deviceReturnDto = new DeviceReturnDto(data, data.length(), // SpecialSecret.getSecretAesStr(secret.getAesKey(), secret.getPrivateRsaKey()), // SpecialSecret.getSecretRSAStr(secret.getPublicRsaKey())); // return deviceReturnDto; // // } /** * * 获取机器的配置信息 * @param deviceConfVo * @return */ public String getDeviceConf(DeviceConfVo deviceConfVo){ if(StringUtils.isEmpty(deviceConfVo.getGorganization()) || StringUtils.isEmpty(deviceConfVo.getOs())){ logger.info("getDeviceConf 缺少参数:{}", JSONObject.toJSONString(deviceConfVo)); return null; } Secret secret = getSecret(deviceConfVo.getGorganization()); if(secret == null){ logger.info("getDeviceConf 获取密钥失败:{}", JSONObject.toJSONString(deviceConfVo)); return null; } // 统一转成小写 OSEnum osEnum = OSEnum.getOS(deviceConfVo.getOs()); DeviceConf deviceConf = deviceConfDao.findEnable(osEnum.getVal()); if(deviceConf == null){ logger.info("getDeviceConf 获取配置信息失败:{}", JSONObject.toJSONString(deviceConfVo)); return null; } JSONObject data = deviceConf.getConfInfo(); try{ logger.info("secret.getAesKey():{} secret.getPrivateRsaKey():{}", secret.getAesKey(), secret.getPrivateRsaKey()); DeviceReturnDto deviceReturnDto = new DeviceReturnDto(data, data.toJSONString().length(), SpecialSecret.getSecretAesStr(secret.getAesKey(), secret.getPrivateRsaKey()), SpecialSecret.getSecretRSAStr(secret.getPublicRsaKey())); return DeformedBase64.encode(JSONObject.toJSONString(deviceReturnDto)); }catch (Exception e){ logger.info("getDeviceConf 获取dll动态库失败:{}", JSONObject.toJSONString(deviceConfVo)); } return null; } /** *TODO 需要考虑设备怎么唯一 * 获取设备唯一id * @param deviceIdVo * @return */ public String getDeviceId(DeviceIdVo deviceIdVo){ if(StringUtils.isEmpty(deviceIdVo.getData()) || StringUtils.isEmpty(deviceIdVo.getOs()) || StringUtils.isEmpty(deviceIdVo.getGorganization())){ logger.info("getDeviceId 传递的参数有误:{}", JSONObject.toJSONString(deviceIdVo)); return null; } OSEnum osEnum = OSEnum.getOS(deviceIdVo.getOs()); if(osEnum == null){ logger.info("getDeviceId 传递的Os参数有误:{}", JSONObject.toJSONString(deviceIdVo)); return null; } //获取密钥 Secret secret = getSecret(deviceIdVo.getGorganization()); if(secret == null){ logger.info("getDeviceId 获取密钥失败:{}", JSONObject.toJSONString(deviceIdVo)); return null; } //解密data String data = SpecialSecret.getData(deviceIdVo.getData(), secret.getAesKey()); if(StringUtils.isEmpty(data)){ logger.info("getDeviceId 传递的data参数有误:{}", JSONObject.toJSONString(deviceIdVo)); return null; } JSONObject dataObject = JSON.parseObject(data); if(dataObject == null){ logger.info("getDeviceId 传递的data参数有误.无法转化json:{}", JSONObject.toJSONString(deviceIdVo)); return null; } //返回唯一值 Map<String, String> reyunIdMap = new HashMap<>(); String clientReyunId = dataObject.getString("reyunId"); if(StringUtils.isEmpty(clientReyunId)){ logger.info("getDeviceId 传递的data参数有误,reyunId取不到:{}", JSONObject.toJSONString(deviceIdVo)); return null; } String deviceId = "";//iOS取IDFA,Android则按照优先级imei/android_id取一个 if(osEnum == OSEnum.IOS){ deviceId = dataObject.getString("idfa"); }else{ deviceId = dataObject.getString("DeviceID"); if(StringUtils.isEmpty(deviceId)){ deviceId = dataObject.getString("AndroidID"); } } String reyunId = getReyunId(clientReyunId, deviceId, secret.getPublicRsaKey()); String reyunIdReal = reyunId.replaceAll("\\\\","");//去掉\反义字符,防止后面转化的时候导致不一致 reyunIdMap.put("reyunId", reyunIdReal); //区分系统保存数据 //去掉转义字符 data = StringUtils.isEmpty(data) ? data : data.replaceAll("\n",""); String dataReal = StringEscapeUtils.unescapeJavaScript(data); JSONObject jsonData = JSONObject.parseObject(dataReal); DeviceInfo deviceInfo = new DeviceInfo(osEnum.getVal(), jsonData, reyunIdReal); // System.out.println("/deviceid 将要保存的数据:"+JSONObject.toJSONString(deviceInfo)); deviceInfoDao.insert(deviceInfo); JSONObject result = (JSONObject) JSON.toJSON(reyunIdMap); try{ DeviceReturnDto deviceReturnDto = new DeviceReturnDto(result, result.toJSONString().length(), SpecialSecret.getSecretAesStr(secret.getAesKey(), secret.getPublicRsaKey()), SpecialSecret.getSecretRSAStr(secret.getPublicRsaKey())); String resultStr = SpecialSecret.aesData(JSONObject.toJSONString(deviceReturnDto), secret.getAesKey()); return resultStr; }catch (Exception e){ logger.info("getDeviceId 获取dll动态库失败:{}", JSONObject.toJSONString(deviceIdVo)); } return null; } private String getReyunId(String clientReyunId, String deviceId, String publicKey ){ String defaultReyunId = "defaultone"; long timestamp = new Date().getTime(); Algorithm alg = new Algorithm(); String shaStr = alg.sha1(clientReyunId + timestamp + deviceId)+defaultReyunId; return DeformedBase64.encode(alg.rsaEncode(shaStr, publicKey)); } // /** // *TODO 需要考虑设备怎么唯一 // * 获取设备唯一id // * @param deviceIdVo // * @return // */ // public DeviceReturnDto getDeviceId(DeviceIdVo deviceIdVo){ // // //解密data // String data = DeformedBase64.decode(deviceIdVo.getData()); // Object dataObject = JSON.parse(data); // if(dataObject == null){ // logger.info("getDeviceId 传递的data参数有误:{}", JSONObject.toJSONString(deviceIdVo)); // return null; // } // // //区分系统保存数据 // if("ios".equalsIgnoreCase(deviceIdVo.getOs())){ // DeviceInfoIos deviceInfoIos = (DeviceInfoIos)dataObject; // deviceInfoIosDao.insert(deviceInfoIos); // }else if("android".equalsIgnoreCase(deviceIdVo.getOs())){ // DeviceInfoAndroid deviceInfoAndroid = (DeviceInfoAndroid)dataObject; // deviceInfoAndroidDao.insert(deviceInfoAndroid); // }else{ // logger.info("getDeviceId 传递的os参数有误:{}", JSONObject.toJSONString(deviceIdVo)); // return null; // } // // //返回唯一值(TODO 此处写成uuid形式,后面需要时间允许按照规则编写) // Map<String, String> reyunIdMap = new HashMap<>(); // reyunIdMap.put("reyunId",UUID.randomUUID()+""); // // Secret secret = getSecret(deviceIdVo.getGorganization()); // if(secret == null){ // logger.info("getDeviceId 获取密钥失败:{}", JSONObject.toJSONString(deviceIdVo)); // return null; // } // // String dataStr = JSONObject.toJSONString(reyunIdMap); // DeviceReturnDto deviceReturnDto = new DeviceReturnDto(dataStr, dataStr.length(), // SpecialSecret.getSecretAesStr(secret.getAesKey(), secret.getPrivateRsaKey()), // SpecialSecret.getSecretRSAStr(secret.getPublicRsaKey())); // // return deviceReturnDto; // } // public Boolean reciveSensorInfo(SensorVo sensorVo){ // // //解密data // String data = DeformedBase64.decode(sensorVo.getData()); // Object dataObject = JSON.parse(data); // if(dataObject == null){ // logger.info("reciveSensorInfo 传递的data参数有误:{}", JSONObject.toJSONString(sensorVo)); // return false; // } // // //区分系统保存数据 // if("ios".equalsIgnoreCase(sensorVo.getOs())){ // SensorInfo sensorInfoIos = (SensorInfo) dataObject; // sensorInfoIosDao.insert(sensorInfoIos); // }else if("android".equalsIgnoreCase(sensorVo.getOs())){ // SensorInfoAndroid sensorInfoAndroid = (SensorInfoAndroid) dataObject; // sensorInfoAndroidDao.insert(sensorInfoAndroid); // }else{ // logger.info("reciveSensorInfo 传递的os参数有误:{}", JSONObject.toJSONString(sensorVo)); // return false; // } // return true; // } public Boolean reciveSensorInfo(SensorVo sensorVo){ //获取密钥 Secret secret = getSecret(sensorVo.getGorganization()); if(secret == null){ logger.info("reciveSensorInfo 获取密钥失败:{}", JSONObject.toJSONString(sensorVo)); return null; } //解密data String data = SpecialSecret.getData(sensorVo.getData(), secret.getAesKey()); if(StringUtils.isEmpty(data)){ logger.info("reciveSensorInfo 传递的data参数有误:{}", JSONObject.toJSONString(sensorVo)); return false; } JSONObject dataObject = JSON.parseObject(data); if(dataObject == null){ logger.info("reciveSensorInfo 传递的data参数有误.无法转化json:{}", JSONObject.toJSONString(sensorVo)); return null; } OSEnum osEnum = OSEnum.getOS(sensorVo.getOs()); //保存数据 String reyunId = dataObject.getString("reyunId"); //去掉转义字符 data = StringUtils.isEmpty(data) ? data : data.replaceAll("\n",""); String dataReal = StringEscapeUtils.unescapeJavaScript(data); JSONObject dataJson = JSONObject.parseObject(dataReal); SensorInfo sensorInfo = new SensorInfo(reyunId, new Date().getTime(), dataJson, osEnum.getVal()); sensorInfoDao.insert(sensorInfo); return true; } /** * 获取私钥公钥 * @param gorganization * @return */ private Secret getSecret(String gorganization){ Secret secret = secretDao.findEnableSecret(gorganization); if(secret == null){ try{ Map<String, Object> keyMap = RSAUtil.initKey(gorganization); String publicKey = RSAUtil.getPublicKey(keyMap); String privateKey = RSAUtil.getPrivateKey(keyMap); String aeskey = SecretUtil.generateAesKey(keyLenth, gorganization); secret = new Secret(gorganization, publicKey, privateKey, aeskey, new Date().getTime(), true); secretDao.insert(secret); }catch (Exception e){ logger.info("生成rsa公钥私钥失败-gorganization:{},-exception:{}",gorganization, e); return null; } } return secret; } public void insertBusinData(BusinData data){ businDataDao.insert(data); } public void insertHeartBeat(HeartBeat heartBeat){ heartBeatDao.insert(heartBeat); } public String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) { // 多次反向代理后会有多个ip值,第一个ip才是真实ip if( ip.indexOf(",")!=-1 ){ ip = ip.split(",")[0]; } } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("X-Real-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } }