最近开发中要求对上传数据进行加密传输,捣鼓了一天,终于有所成
1,BASE64.java
package com.gdhuihe.face.utils; public class BASE64 { static public byte[] encode(byte[] data) { char[] out = new char[((data.length + 2) / 3) * 4]; for (int i = 0, index = 0; i < data.length; i += 3, index += 4) { boolean quad = false; boolean trip = false; int val = (0xFF & (int) data[i]); val <<= 8; if ((i + 1) < data.length) { val |= (0xFF & (int) data[i + 1]); trip = true; } val <<= 8; if ((i + 2) < data.length) { val |= (0xFF & (int) data[i + 2]); quad = true; } out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)]; val >>= 6; out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)]; val >>= 6; out[index + 1] = alphabet[val & 0x3F]; val >>= 6; out[index + 0] = alphabet[val & 0x3F]; } return new String(out).getBytes(); } static public byte[] decode(byte[] data) throws Exception { int len = ((data.length + 3) / 4) * 3; if (data.length > 0 && data[data.length - 1] == '=') --len; if (data.length > 1 && data[data.length - 2] == '=') --len; byte[] out = new byte[len]; int shift = 0; int accum = 0; int index = 0; for (int ix = 0; ix < data.length; ix++) { int value = codes[data[ix] & 0xFF]; if (value >= 0) { accum <<= 6; shift += 6; accum |= value; if (shift >= 8) { shift -= 8; out[index++] = (byte) ((accum >> shift) & 0xff); } } } if (index != out.length) throw new Exception("miscalculated data length!"); return out; } static private char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" .toCharArray(); static private byte[] codes = new byte[256]; static { for (int i = 0; i < 256; i++) codes[i] = -1; for (int i = 'A'; i <= 'Z'; i++) codes[i] = (byte) (i - 'A'); for (int i = 'a'; i <= 'z'; i++) codes[i] = (byte) (26 + i - 'a'); for (int i = '0'; i <= '9'; i++) codes[i] = (byte) (52 + i - '0'); codes['+'] = 62; codes['/'] = 63; } }
2,ServerDES.java
package com.gdhuihe.face.utils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.gdhuihe.face.model.request.CardInfo; import org.apache.commons.lang.StringUtils; import org.springframework.web.multipart.MultipartFile; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import javax.imageio.stream.FileImageOutputStream; import java.io.*; import java.util.UUID; public class ServerDES { private static byte[] iv1 = "63814769".getBytes(); private static byte[] mKey = "01528763".getBytes(); //将字节数解密为字符串 public static String decryptResultString(byte[] decryptBytes) throws Exception { return new String(decrypt(decryptBytes)); } //解密方法 public static byte[] decrypt(byte[] decryptBytes) throws Exception { IvParameterSpec iv = new IvParameterSpec(iv1); SecretKeySpec key = new SecretKeySpec(mKey, "DES"); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, key, iv); return cipher.doFinal(BASE64.decode(decryptBytes)); } /**** * 将字符串加密为字节数 * @param encryptString * @return * @throws Exception */ public static byte[] encrypt(String encryptString) throws Exception { return encrypt(encryptString.getBytes()); } public static byte[] encrypt(byte[] bytes) throws Exception { IvParameterSpec iv = new IvParameterSpec(iv1); DESKeySpec dks = new DESKeySpec(mKey); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(dks); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, iv); return BASE64.encode(cipher.doFinal(bytes)); } /*** * 解密文件流 * @param file * @return */ public static byte[] decodeFile(byte[] file){ byte[] newFile= new byte[0]; try { newFile = decrypt(file); } catch (Exception e) { e.printStackTrace(); } return newFile; } public static byte[] File2byte(String filePath) { byte[] buffer = null; try { File file = new File(filePath); FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int n; while ((n = fis.read(b)) != -1) { bos.write(b, 0, n); } fis.close(); bos.close(); buffer = bos.toByteArray(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return buffer; } /** * 将文件头转换成16进制字符串 * * @param * @return 16进制字符串 */ private static String bytesToHexString(byte[] src){ StringBuilder stringBuilder = new StringBuilder(); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } /** * 判断文件类型 * * @param * @return 文件类型 */ public static FileType getType(byte[] src) throws IOException { String fileHead = bytesToHexString(src); if (fileHead == null || fileHead.length() == 0) { return null; } fileHead = fileHead.toUpperCase(); FileType[] fileTypes = FileType.values(); for (FileType type : fileTypes) { if (fileHead.startsWith(type.getValue())) { return type; } } return null; } //将加密后的byte数组到图片到硬盘上 public static String byte2image(byte[] data,String filePath){ // 生成uuid作为文件名称 String uuid = ""; uuid = UUID.randomUUID().toString().replaceAll("-", "") + System.currentTimeMillis() + Tools.getRandomStr(); // 获得文件类型(可以判断如果不是图片,禁止上传) String path = ""; String index="png"; try { FileType contentType = getType(data); if(null!=contentType){ index=contentType.name().toLowerCase(); } // 获得文件后缀名称 path = uuid + "." + index; FileImageOutputStream imageOutput = new FileImageOutputStream(new File(filePath + path));//打开输入流 imageOutput.write(data, 0, data.length);//将byte写入硬盘 imageOutput.close(); return path; } catch(Exception ex) { ex.printStackTrace(); return ""; } } public static InputStream byte2ToInputStream(byte[] file){ InputStream inputStream = new ByteArrayInputStream(file); return inputStream; } /**** * 解密字符串 * @param str * @return */ public static String decodeString(String str){ String code=""; try { code= decryptResultString(str.getBytes()); } catch (Exception e) { e.printStackTrace(); } return code; } /**** * 将加密后的字符解析为上传数据对象 * @param deviceData * @return */ public static CardInfo decodeJson(String deviceData){ CardInfo cardInfo= JSON.parseObject(decodeString(deviceData),new TypeReference<CardInfo>() {}); return cardInfo; } public static void main(String[] args) { String sd = "你好hello,对接平台theplatform to compile"; String str = ""; byte[] deStr; String encrpt="xrGaq5G0nMlz4OIeAmjZA21ffk/+m8mN5BStwXuiVwfLyvd/v7tyWTaRRmnHVa+1fYqf5iu6C1Q="; try { // System.out.println("decrypt:" + decryptResultString(xs.getBytes("utf-8"))); // byte[] bytes = encrypt(str); //String enc = new String(bytes, "UTF-8"); // System.out.println(enc);//加密后的密文 // System.out.println("encrpt:" + decryptResultString(enc.getBytes()));//解密后的密文 // System.out.println("decrypt:" + decryptResultString(bytes));//解密 // byte[] bytes=encrypt(encrpt); // System.out.println(decryptResultString(bytes)); /* byte[] desfile=encrypt(filebyte);//加密后的文件流 System.out.println(desfile); System.out.println(byte2image(desfile,"E:"));*/ } catch (Exception e) { e.printStackTrace(); } } }
FileType.java
package com.gdhuihe.face.utils; public enum FileType { /** * JEPG. */ JPEG("FFD8FF"), /** * PNG. */ PNG("89504E47"), /** * GIF. */ GIF("47494638"), /** * TIFF. */ TIFF("49492A00"), /** * Windows Bitmap. */ BMP("424D"), /** * CAD. */ DWG("41433130"), /** * Adobe Photoshop. */ PSD("38425053"), /** * Rich Text Format. */ RTF("7B5C727466"), /** * XML. */ XML("3C3F786D6C"), /** * HTML. */ HTML("68746D6C3E"), /** * Email [thorough only]. */ EML("44656C69766572792D646174653A"), /** * Outlook Express. */ DBX("CFAD12FEC5FD746F"), /** * Outlook (pst). */ PST("2142444E"), /** * MS Word/Excel. */ XLS_DOC("D0CF11E0"), /** * MS Access. */ MDB("5374616E64617264204A"), /** * WordPerfect. */ WPD("FF575043"), /** * Postscript. */ EPS("252150532D41646F6265"), /** * Adobe Acrobat. */ PDF("255044462D312E"), /** * Quicken. */ QDF("AC9EBD8F"), /** * Windows Password. */ PWL("E3828596"), /** * ZIP Archive. */ ZIP("504B0304"), /** * RAR Archive. */ RAR("52617221"), /** * Wave. */ WAV("57415645"), /** * AVI. */ AVI("41564920"), /** * Real Audio. */ RAM("2E7261FD"), /** * Real Media. */ RM("2E524D46"), /** * MPEG (mpg). */ MPG("000001BA"), /** * Quicktime. */ MOV("6D6F6F76"), /** * Windows Media. */ ASF("3026B2758E66CF11"), /** * MIDI. */ MID("4D546864"); private String value = ""; /** * Constructor. */ private FileType(String value) { this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
CardInfo.java 加密对象
package com.gdhuihe.face.model.request; /** * Created by Stefan on 2018/11/19. */ public class CardInfo { private String confidence; private String macAddress; private String address; private String birthday; private String expireDate; private String idcardNo; private String name; private String nation; private String sex; private String signDate; private String tel; private String matchScore; private String validDate; private String threshold; private String signOrganization; private String pixel; private String signResult; private byte[] filePic; private byte[] fileHead; private String deviceType; public String getConfidence() { return confidence; } public void setConfidence(String confidence) { this.confidence = confidence; } public String getMacAddress() { return macAddress; } public void setMacAddress(String macAddress) { this.macAddress = macAddress; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public String getExpireDate() { return expireDate; } public void setExpireDate(String expireDate) { this.expireDate = expireDate; } public String getIdcardNo() { return idcardNo; } public void setIdcardNo(String idcardNo) { this.idcardNo = idcardNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNation() { return nation; } public void setNation(String nation) { this.nation = nation; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getSignDate() { return signDate; } public void setSignDate(String signDate) { this.signDate = signDate; } public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } public String getMatchScore() { return matchScore; } public void setMatchScore(String matchScore) { this.matchScore = matchScore; } public String getValidDate() { return validDate; } public void setValidDate(String validDate) { this.validDate = validDate; } public String getThreshold() { return threshold; } public void setThreshold(String threshold) { this.threshold = threshold; } public String getSignOrganization() { return signOrganization; } public void setSignOrganization(String signOrganization) { this.signOrganization = signOrganization; } public String getPixel() { return pixel; } public void setPixel(String pixel) { this.pixel = pixel; } public String getSignResult() { return signResult; } public void setSignResult(String signResult) { this.signResult = signResult; } public byte[] getFilePic() { return filePic; } public void setFilePic(byte[] filePic) { this.filePic = filePic; } public byte[] getFileHead() { return fileHead; } public void setFileHead(byte[] fileHead) { this.fileHead = fileHead; } public String getDeviceType() { return deviceType; } public void setDeviceType(String deviceType) { this.deviceType = deviceType; } }
上传文件的接口:
/** * 上传加密身份证刷卡记录 */ @RequestMapping(value = "/uploadData",method = RequestMethod.POST) @ResponseBody @ApiOperation(value = "上传加密身份证刷卡记录api接口", httpMethod = "POST") public Result<Boolean> uploadData(@RequestBody String deviceData) { CardInfo cardInfo=ServerDES.decodeJson(deviceData); if (cardInfo.getFileHead() == null || cardInfo.getFileHead().length <0) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } if (cardInfo.getFilePic() == null || cardInfo.getFilePic().length <0) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String ipPort = getLocalIpPort(); if (StringUtils.isEmpty(cardInfo.getMacAddress())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String macAddress= cardInfo.getMacAddress(); if (StringUtils.isEmpty(cardInfo.getName())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String name=cardInfo.getName(); if (StringUtils.isEmpty(cardInfo.getNation())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String nation=cardInfo.getNation(); if (StringUtils.isEmpty(cardInfo.getSex())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } long sex=Long.parseLong(cardInfo.getSex()); if (StringUtils.isEmpty(cardInfo.getBirthday())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String birthday=cardInfo.getBirthday(); if (StringUtils.isEmpty(cardInfo.getAddress())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String address=cardInfo.getAddress(); if (StringUtils.isEmpty(cardInfo.getIdcardNo())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String idcardNo=cardInfo.getIdcardNo(); if (StringUtils.isEmpty(cardInfo.getSignOrganization())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String signOrganization=cardInfo.getSignOrganization(); if (StringUtils.isEmpty(cardInfo.getValidDate())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String validDate=cardInfo.getValidDate(); if (StringUtils.isEmpty(cardInfo.getExpireDate())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String expireDate=cardInfo.getExpireDate(); if (StringUtils.isEmpty(cardInfo.getSignDate())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String signDate=cardInfo.getSignDate(); if (StringUtils.isEmpty(cardInfo.getPixel())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String pixelList=cardInfo.getPixel(); if (StringUtils.isEmpty(cardInfo.getSignResult())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String signResult=cardInfo.getSignResult(); if (StringUtils.isEmpty(cardInfo.getThreshold())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String threshold=cardInfo.getThreshold(); if (StringUtils.isEmpty(cardInfo.getMatchScore())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String matchScore=cardInfo.getMatchScore(); if (StringUtils.isEmpty(cardInfo.getConfidence())) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } String confidence=cardInfo.getConfidence(); String tel=cardInfo.getTel(); String deviceType=cardInfo.getDeviceType(); //pixel 截图需要的像素点 String[] pixel=pixelList.split(","); if (null == pixel || pixel.length<4) { return ResultUtil.failWithMsg(ErrorCode.MISSINGPARAM); } // 检测这个设备是否正常 TMDevice device = deviceService.getByMacAddress(macAddress); if (device == null) { device = new TMDevice(); device.setCustomerId(10001l); device.setMacAddress(macAddress); if(StringUtils.isNotEmpty(deviceType)){ device.setDeviceType(Long.parseLong(deviceType)); }else { device.setDeviceType(1l); } Calendar c = Calendar.getInstance();//可以对每个时间域单独修改 int hour = c.get(Calendar.HOUR_OF_DAY); int minute = c.get(Calendar.MINUTE); device.setDeviceName(hour + "点"+ minute + "分新增的设备"); device.setAddTime(new Date()); device.setIsDelete(0l); device.setIsNeedPhone(0l); if (deviceService.addDevice(device)) { device = deviceService.getByMacAddress(macAddress); device.setDeviceCode("SN.1" + String.format("%07d", device.getDeviceId())); device.setLastLogin(new Date()); deviceService.updateDevice(device); } } else { if("".equals(device.getDeviceCode())) { // deviceCode 更新上 device.setDeviceCode("SN.1" + String.format("%07d", device.getDeviceId())); deviceService.updateDevice(device); } if(device.getCustomerId() == 0) { device.setCustomerId(10001l); deviceService.updateDevice(device); } // 更新每次的时间 device.setLastLogin(new Date()); deviceService.updateDevice(device); } TMDevice tInfoDevice = device; return new ApiCall<Boolean>() { @Override protected Boolean process() throws BizException { DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition(); defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = transactionManager.getTransaction(defaultTransactionDefinition); try { // 保存访客信息 TMVisitor tmVisitor = tInfoVisitorService.findByIdcardNo(idcardNo, validDate); if (tmVisitor == null) { Lock lock = new ReentrantLock(); lock.lock(); try { String birth = birthday .replaceAll("年","-") .replaceAll("月","-") .replaceAll("日",""); tmVisitor = new TMVisitor(); tmVisitor.setName(name); tmVisitor.setSex(sex); tmVisitor.setNation(nation); tmVisitor.setBirthday(Timestamp.valueOf(birth + " 00:00:00")); tmVisitor.setAddress(address); tmVisitor.setIdCard(idcardNo); tmVisitor.setDepart(signOrganization); tmVisitor.setValidStart(Timestamp.valueOf(validDate + " 00:00:00")); tmVisitor.setValidEnd(Timestamp.valueOf(expireDate + " 00:00:00")); tmVisitor.setAddTime(new Timestamp(System.currentTimeMillis())); tmVisitor.setCustomerId(tInfoDevice.getCustomerId()); tInfoVisitorService.save(tmVisitor); long visitorId = tInfoVisitorService.getLastInsertId(); tmVisitor.setVisitorId(visitorId); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } //上传头像 String name = ServerDES.byte2image(cardInfo.getFileHead(), rootPath + headPath); tmVisitor.setHeaderUrl(ipPort + headPath + name); tInfoVisitorService.update(tmVisitor); } // 保存访客记录 TRecordVisitor tRecordVisitor = new TRecordVisitor(); tRecordVisitor.setDeviceId(tInfoDevice.getDeviceId()); tRecordVisitor.setOrgId(tInfoDevice.getOrgId()); tRecordVisitor.setVisitorId(tmVisitor.getVisitorId()); if(StringUtils.isNotEmpty(signResult)){ tRecordVisitor.setSignResult(Long.parseLong(signResult)); }else { tRecordVisitor.setSignResult(1l); } //保存全景图路径 String picName = ServerDES.byte2image(cardInfo.getFilePic(), rootPath + photoPath); tRecordVisitor.setVisitPicUrl(ipPort + photoPath + picName); //保存截图 int pixel0=Integer.parseInt(pixel[0]); int pixel1=Integer.parseInt(pixel[1]); int pixel2=Integer.parseInt(pixel[2]); int pixel3=Integer.parseInt(pixel[3]); String faceName= fileUploadUtil.cutImage(ServerDES.byte2ToInputStream(cardInfo.getFilePic()), rootPath + facePath,pixel0 ,pixel1,pixel2,pixel3); tRecordVisitor.setVisitFaceUrl(ipPort + facePath + faceName); tRecordVisitor.setPicCode("FK"+macAddress.replace(":","").toUpperCase()+System.currentTimeMillis()); tRecordVisitor.setCreateTime(new Date()); tRecordVisitor.setVisitTime(Timestamp.valueOf(signDate)); //tRecordVisitor.setVisitTime(new Date()); if(threshold != null) { tRecordVisitor.setThreshold(Float.parseFloat(threshold)); }else { tRecordVisitor.setThreshold(0f); } if(StringUtils.isEmpty(matchScore)){ tRecordVisitor.setMatchScore(0f); }else { tRecordVisitor.setMatchScore(Float.parseFloat(matchScore)); } tRecordVisitor.setPhone(tel); tRecordVisitor.setConfidence(BigDecimal.valueOf(Double.parseDouble(confidence))); tRecordVisitor.setSecondDiff(getVisitorLeadTime(tRecordVisitor.getDeviceId(),tRecordVisitor.getVisitorId(),signDate)); tRecordVisitor.setStatus(1l); tRecordVisitor.setCustomerId(tInfoDevice.getCustomerId()); if(StringUtils.isEmpty(tRecordVisitor.getVisitPicUrl())){ return false; } recordVisitorService.save(tRecordVisitor); long visitId = recordVisitorService.getLastInsertId(tRecordVisitor.getVisitorId(),tRecordVisitor.getDeviceId()); //使用身份证号跟黑名单库做比较,如果存在信息则写入表中(消息写入格式:(xx库的xx在xx网吧出现上网行为!)) tRecordWarnService.checkVisitor(tmVisitor.getIdCard(),tRecordVisitor.getOrgId(),visitId,signDate); transactionManager.commit(status); return true; } catch (Exception e) { transactionManager.rollback(status); //访客照片上传失败! e.printStackTrace(); return false; } } }.execute(); }