tao.mo

kafka-cndc-server | 修改 | 加解密开发,字段赋值不完整调整

mt
2024年12月17日18:19:26
Showing 20 changed files with 1152 additions and 10 deletions
......@@ -52,10 +52,10 @@ public class AttachmentUtil {
private void initAttachment(Attachment attachment,String bizType,User user) throws Exception{
DictionaryEntries attachmentBizTypeEntries = cacheSystem.getDicAttachmentBizType(bizType);
attachment.setBizTypeCode(attachmentBizTypeEntries.getCode());
attachment.setBizTypeName(attachmentBizTypeEntries.getDescription());
attachment.setBizTypeName(attachmentBizTypeEntries.getEnglishName());
DictionaryEntries attachmentFileTypeEntries = cacheSystem.getDicAttachmentFileType(AttachmentFileTypeEnum.FILE.getCode());
attachment.setFileTypeCode(attachmentFileTypeEntries.getCode());
attachment.setFileTypeName(attachmentFileTypeEntries.getDescription());
attachment.setFileTypeName(attachmentFileTypeEntries.getEnglishName());
attachment.setStatus(StatusEnum.YES.getCode());
attachment.setCreateUserId(user.getId());
attachment.setCreateUserName(user.getUserName());
......
......@@ -78,7 +78,7 @@ public class ConsignmentUtil {
consignment.setSubmitterId(user.getId());
//记录当前提交运单状态
consignment.setStatusCode(consignmentStatusDic.getCode());
consignment.setStatusName(consignmentStatusDic.getDescription());
consignment.setStatusName(consignmentStatusDic.getEnglishName());
/**
* 初始化基础字段
*/
......
......@@ -36,7 +36,7 @@ public class PushObUtil {
pushOb.setConsignmentCode(consignment.getConsignmentCode());
pushOb.setPushNum(DigitConstants.DIGIT_ZERO_LONG);
pushOb.setStatusCode(pushObStatus.getCode());
pushOb.setStatusName(pushObStatus.getDescription());
pushOb.setStatusName(pushObStatus.getEnglishName());
pushOb.setCreateUserId(user.getId());
pushOb.setCreateUserName(user.getUserName());
pushOb.setModifyUserId(user.getId());
......
......@@ -35,7 +35,7 @@ public class UploadRecordUtil {
uploadRecord.setConsignmentCode(consignmentCode);
//记录当前运单状态
uploadRecord.setStatusCode(consignmentStatusDic.getCode());
uploadRecord.setStatusName(consignmentStatusDic.getDescription());
uploadRecord.setStatusName(consignmentStatusDic.getEnglishName());
/**
* 初始化基础字段
*/
......
package com.fedex.connect.common.annotation;
import java.lang.annotation.*;
/**
* @Author mt
* @Description 实体注解
* @Date 2024/12/17
*/
@Target({ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SensitiveEntity {
}
\ No newline at end of file
package com.fedex.connect.common.annotation;
import java.lang.annotation.*;
/**
* @Author mt
* @Description 字段注解
* @Date 2024/12/17
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SensitiveField {
}
\ No newline at end of file
package com.fedex.connect.common.model.biz;
import com.fedex.connect.common.annotation.SensitiveEntity;
import com.fedex.connect.common.annotation.SensitiveField;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* DESC: CE501报文业务表
* DESC: CE501报文业务表,增加需要加密标志
* TABLE: ICLEARIMP.T_BIZ_CE_INFO
*/
@SensitiveEntity
public class CeInfo implements Serializable {
/**
* ID,自动增加
......@@ -92,11 +96,13 @@ public class CeInfo implements Serializable {
/**
* 发货联系人姓名
*/
@SensitiveField
private String shipperContactName;
/**
* 发货人手机号
*/
@SensitiveField
private String shipperPhone;
/**
......
package com.fedex.connect.common.model.biz;
import com.fedex.connect.common.annotation.SensitiveEntity;
import com.fedex.connect.common.annotation.SensitiveField;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
......@@ -8,6 +11,7 @@ import java.util.Date;
* DESC: 运单表
* TABLE: T_BIZ_CONSIGNMENT
*/
@SensitiveEntity
public class Consignment implements Serializable {
/**
* ID,自动增加
......@@ -67,11 +71,13 @@ public class Consignment implements Serializable {
/**
* 发货联系人姓名
*/
@SensitiveField
private String shipperContactName;
/**
* 发货人手机号
*/
@SensitiveField
private String shipperPhone;
/**
......
package com.fedex.connect.common.model.sys;
import com.fedex.connect.common.annotation.SensitiveEntity;
import com.fedex.connect.common.annotation.SensitiveField;
import java.io.Serializable;
import java.util.Date;
......@@ -7,6 +10,7 @@ import java.util.Date;
* DESC: 用户表
* TABLE: ICLEARIMP.T_SYS_USER
*/
@SensitiveEntity
public class User implements Serializable {
/**
* ID,主键自增
......@@ -21,6 +25,7 @@ public class User implements Serializable {
/**
* 用户姓名
*/
@SensitiveField
private String userName;
/**
......@@ -41,6 +46,7 @@ public class User implements Serializable {
/**
* 联系电话
*/
@SensitiveField
private String phone;
/**
......
package com.fedex.connect.common.dependencies.interceptor;
import com.fedex.connect.common.annotation.SensitiveEntity;
import com.fedex.connect.common.dependencies.service.sys.IAesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.*;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Properties;
@Component
@Intercepts({
@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
@Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class),
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
@Slf4j
public class MyBatisInterceptor implements Interceptor {
@Resource
private IAesService aesService;
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget();
//拦截sql结果处理器
if (target instanceof ResultSetHandler) {
return resultDecrypt(invocation);
}
//拦截sql参数处理器
if (target instanceof ParameterHandler) {
return parameterEncrypt(invocation);
}
//拦截sql语句处理器
if (target instanceof StatementHandler) {
return replaceSql(invocation);
}
return invocation.proceed();
}
/**
* 对mybatis映射结果进行字段解密
*
* @param invocation 参数
* @return 结果
* @throws Throwable 异常
*/
private Object resultDecrypt(Invocation invocation) throws Throwable {
//取出查询的结果
Object resultObject = invocation.proceed();
if (Objects.isNull(resultObject)) {
return null;
}
//基于selectList
if (resultObject instanceof ArrayList) {
ArrayList resultList = (ArrayList) resultObject;
if (CollectionUtils.isEmpty(resultList)) {
return resultObject;
}
for (Object result : resultList) {
if (needToDecrypt(result)) {
//逐一解密
aesService.decrypt(result);
}
}
//基于selectOne
} else {
if (needToDecrypt(resultObject)) {
aesService.decrypt(resultObject);
}
}
return resultObject;
}
/**
* mybatis映射参数进行加密
*
* @param invocation 参数
* @return 结果
* @throws Throwable 异常
*/
private Object parameterEncrypt(Invocation invocation) throws Throwable {
//@Signature 指定了 type= parameterHandler 后,这里的 invocation.getTarget() 便是parameterHandler
//若指定ResultSetHandler ,这里则能强转为ResultSetHandler
ParameterHandler parameterHandler = (ParameterHandler) invocation.getTarget();
// 获取参数对像,即 mapper 中 paramsType 的实例
Field parameterField = parameterHandler.getClass().getDeclaredField("parameterObject");
parameterField.setAccessible(true);
//取出实例
Object parameterObject = parameterField.get(parameterHandler);
if(parameterHandler.getParameterObject() instanceof MapperMethod.ParamMap){
MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap) parameterHandler.getParameterObject();
parameterObject = paramMap.get("param1");
}
if (null == parameterObject) {
return invocation.proceed();
}
Class<?> parameterObjectClass = parameterObject.getClass();
//校验该实例的类是否被@SensitiveEntity所注解
SensitiveEntity sensitiveEntity = AnnotationUtils.findAnnotation(parameterObjectClass, SensitiveEntity.class);
//未被@SensitiveEntity所注解 则为null
if (Objects.isNull(sensitiveEntity)) {
return invocation.proceed();
}
//取出当前当前类所有字段,传入加密方法
Field[] allFields = parameterObjectClass.getDeclaredFields();
aesService.encrypt(allFields, parameterObject);
return invocation.proceed();
}
/**
* 替换mybatis Sql中的加密Key
*
* @param invocation 参数
* @return 结果
* @throws Throwable 异常
*/
private Object replaceSql(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
BoundSql boundSql = statementHandler.getBoundSql();
//获取到原始sql语句
String sql = boundSql.getSql();
if (null == sql){
return invocation.proceed();
}
//通过反射修改sql语句
Field field = boundSql.getClass().getDeclaredField("sql");
field.setAccessible(true);
field.set(boundSql, sql);
return invocation.proceed();
}
/**
* 判断是否包含需要加解密对象
*
* @param object 参数
* @return 结果
*/
private boolean needToDecrypt(Object object) {
if(Objects.isNull(object)){
return false;
}
Class<?> objectClass = object.getClass();
Class<?> parentClass = objectClass.getSuperclass();
SensitiveEntity sensitiveEntity = AnnotationUtils.findAnnotation(objectClass, SensitiveEntity.class);
SensitiveEntity parentSensitiveEntity = AnnotationUtils.findAnnotation(parentClass, SensitiveEntity.class);
return Objects.nonNull(sensitiveEntity) || Objects.nonNull(parentSensitiveEntity);
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}
package com.fedex.connect.common.dependencies.service.sys;
import java.lang.reflect.Field;
public interface IAesService {
<T> T encrypt(Field[] declaredFields, T paramsObject) throws Exception;
<T> T decrypt(T result) throws Exception;
}
package com.fedex.connect.common.dependencies.service.sys.impl;
import com.fedex.connect.common.annotation.SensitiveField;
import com.fedex.connect.common.dependencies.service.sys.IAesService;
import com.fedex.connect.common.dependencies.util.arithmetic.AesFieldUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.Objects;
@Service
public class AesServiceImpl implements IAesService {
@Resource
private AesFieldUtils aesFieldUtils;
@Override
public <T> T encrypt(Field[] declaredFields, T paramsObject) throws Exception {
for (Field field : declaredFields) {
//取出所有被EncryptDecryptField注解的字段
SensitiveField sensitiveField = field.getAnnotation(SensitiveField.class);
if (Objects.isNull(sensitiveField)) {
continue;
}
field.setAccessible(true);
Object object = field.get(paramsObject);
//暂时只实现String类型的加密
if (object instanceof String) {
String value = (String) object;
//如果映射字段值为空,并且以==结尾则跳过不进行加密
if (StringUtils.isEmpty(value) || aesFieldUtils.isBase64(value)) {
continue;
}
//加密 这里我使用自定义的AES加密工具
field.set(paramsObject, aesFieldUtils.encrypt(value));
}
}
return paramsObject;
}
@Override
public <T> T decrypt(T result) throws Exception {
//取出resultType的类
Class<?> resultClass = result.getClass();
Field[] allFields = resultClass.getDeclaredFields();
for (Field field : allFields) {
//取出所有被EncryptDecryptField注解的字段
SensitiveField sensitiveField = field.getAnnotation(SensitiveField.class);
if (Objects.isNull(sensitiveField)) {
continue;
}
field.setAccessible(true);
Object object = field.get(result);
//只支持String的解密
if (object instanceof String) {
String value = (String) object;
//如果映射字段值为空,并且不已==结尾则跳过不进行解密
if (StringUtils.isBlank(value) || !aesFieldUtils.isBase64(value)) {
continue;
}
//对注解的字段进行逐一解密
field.set(result, aesFieldUtils.decrypt(value));
}
}
return result;
}
}
\ No newline at end of file
package com.fedex.connect.common.dependencies.util.arithmetic;
/**
* 密钥的长度
*/
public enum AESType {
AES_128(128),
AES_192(192),
AES_256(256);
public int value;
private AESType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
package com.fedex.connect.common.dependencies.util.arithmetic;
import com.fedex.connect.common.dependencies.util.BytesUtils;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* AES加密解密工具里
*/
public class AESUtil {
/**
* 指定编码格式
*/
public static final String CHARSET = "UTF-8";
/**
* 设定秘钥
*/
public static final String key = "com123fedex456export789tw0";
public static void main(String[] args) throws Exception{
String content = "测试加密界面字符串";
byte[] encryptByte;
byte[] decodeByte;
String encodeStr;
String decodeStr;
encryptByte = encode_SysDefault(content);
encodeStr = BytesUtils.bytesToHexString(encryptByte);
System.out.println("加密后:" + encodeStr);
//数据库存储值转换后解密
byte[] dataColumnValue = BytesUtils.hexStringToBytes(encodeStr);
decodeByte = decode_SysDefault(dataColumnValue);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("系统默认解密后:" + decodeStr);
/**
* AES不指定模式和填充,默认为 ECB/PKCS5Padding
* AES/ECB
* AES/ECB/NoPadding
* AES/ECB/PKCS5Padding
* AES/ECB/ISO10126Padding
*/
/* System.out.println("AES ECB 128");
encryptByte = encode_AES_ECB_128(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_ECB_128(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);
System.out.println("AES ECB 192");
encryptByte = encode_AES_ECB_192(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_ECB_192(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);
System.out.println("AES ECB 256");
encryptByte = encode_AES_ECB_256(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_ECB_256(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);*/
/**
* AES/CBC
* AES/CBC/NoPadding
* AES/CBC/PKCS5Padding
* AES/CBC/ISO10126Padding
*/
/*System.out.println("AES CBC 128");
content = "必须十六必须十六必须十六必须十六";
encryptByte = encode_AES_CBC_128(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_CBC_128(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);
System.out.println("AES CBC 192");
content = "不是必须十六";
encryptByte = encode_AES_CBC_192(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_CBC_192(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);
System.out.println("AES CBC 256");
content = "不是必须十六";
encryptByte = encode_AES_CBC_256(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_CBC_256(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);
*/
/**
* AES/CFB
* AES/CBC/NoPadding
* AES/CBC/PKCS5Padding
* AES/CBC/ISO10126Padding
*/
/*System.out.println("AES CFB 128");
encryptByte = encode_AES_CFB_128(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_CFB_128(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);
System.out.println("AES CFB 192");
encryptByte = encode_AES_CFB_192(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_CFB_192(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);
System.out.println("AES CFB 256");
encryptByte = encode_AES_CFB_256(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_CFB_256(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);*/
/**
* AES/OFB
* AES/OFB/NoPadding
* AES/OFB/PKCS5Padding
* AES/OFB/ISO10126Padding
*/
/*System.out.println("AES OFB 128");
encryptByte = encode_AES_OFB_128(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_OFB_128(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);
System.out.println("AES OFB 192");
encryptByte = encode_AES_OFB_192(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_OFB_192(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);
System.out.println("AES OFB 256");
encryptByte = encode_AES_OFB_256(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_OFB_256(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);*/
/**
* 1.5 AES/PCBC
* AES/PCBC/NoPadding
* AES/PCBC/PKCS5Padding
* AES/PCBC/ISO10126Padding
*/
/*System.out.println("AES PCBC 128");
encryptByte = encode_AES_PCBC_128(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_PCBC_128(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);
System.out.println("AES PCBC 192");
encryptByte = encode_AES_PCBC_192(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_PCBC_192(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);
System.out.println("AES PCBC 256");
encryptByte = encode_AES_PCBC_256(content);
encodeStr = TypeConvert.bytesToHexString(encryptByte);
System.out.println("加密后为:" + encodeStr);
decodeByte = decode_AES_PCBC_256(encryptByte);
decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后:" + decodeStr);*/
}
/**
* 默认加密封装
* @param eVal 待加密字符串
* @return 加密后字符串
*/
public static String encode_default(String eVal){
if (StringUtils.isBlank(eVal)){
return null;
}
try{
byte[] encode_valByte = encode_SysDefault(StringUtils.trimToEmpty(eVal));
return BytesUtils.bytesToHexString(encode_valByte);
} catch (Exception e){
return null;
}
}
/**
* 默认解密封装
* @param dVal 待解密字符串
* @return 解密后字符串
*/
public static String decode_default(String dVal){
if (StringUtils.isBlank(dVal)){
return null;
}
try{
byte[] valByte = BytesUtils.hexStringToBytes(dVal);
byte[] decode_valByte = decode_SysDefault(valByte);
return new String(decode_valByte, CHARSET);
} catch (Exception e){
return null;
}
}
/**
* 判断入参值。是否已经加密。
* @param val
* @return
*/
public static boolean checkIsEncode(String val){
//加密的绝对很长
if (val.length() < 3){
return false;
}
try{
//尝试解密
byte[] dataColumnValue = BytesUtils.hexStringToBytes(val);
byte[] decodeByte = decode_SysDefault(dataColumnValue);
String decodeStr = new String(decodeByte, CHARSET);
//如果解密后和原数据一样。可能是没有加密
if (val.equals(decodeStr)){
return false;
}
//如果解密后和原数据不一致,说明加密过了。
return true;
}catch (Exception e){
//如果异常,说明没有加密
return false;
}
}
/**
* 系统默认采用加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_SysDefault(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_256,EncodeType.AES_CBC_ISO10126PADDING);
}
/**
* 系统默认采用解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_SysDefault(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_256,EncodeType.AES_CBC_ISO10126PADDING);
}
/**
* AES_PCBC_128加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_PCBC_128(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_128,EncodeType.AES_PCBC_PKCS5PADDING);
}
/**
* AES_PCBC_128 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_PCBC_128(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_128,EncodeType.AES_PCBC_PKCS5PADDING);
}
/**
* AES_PCBC_192加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_PCBC_192(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_192,EncodeType.AES_PCBC_PKCS5PADDING);
}
/**
* AES_PCBC_192 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_PCBC_192(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_192,EncodeType.AES_PCBC_PKCS5PADDING);
}
/**
* AES_PCBC_256加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_PCBC_256(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_256,EncodeType.AES_PCBC_PKCS5PADDING);
}
/**
* AES_PCBC_256 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_PCBC_256(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_256,EncodeType.AES_PCBC_PKCS5PADDING);
}
/**
* AES_OFB_128加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_OFB_128(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_128,EncodeType.AES_OFB_PKCS5PADDING);
}
/**
* AES_OFB_128 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_OFB_128(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_128,EncodeType.AES_OFB_PKCS5PADDING);
}
/**
* AES_OFB_192加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_OFB_192(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_192,EncodeType.AES_OFB_PKCS5PADDING);
}
/**
* AES_OFB_192 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_OFB_192(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_192,EncodeType.AES_OFB_PKCS5PADDING);
}
/**
* AES_OFB_256加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_OFB_256(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_256,EncodeType.AES_OFB_PKCS5PADDING);
}
/**
* AES_OFB_256 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_OFB_256(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_256,EncodeType.AES_OFB_PKCS5PADDING);
}
/**
* AES_CFB_128加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_CFB_128(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_128,EncodeType.AES_CFB_PKCS5PADDING);
}
/**
* AES_CFB_128 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_CFB_128(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_128,EncodeType.AES_CFB_PKCS5PADDING);
}
/**
* AES_CFB_192加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_CFB_192(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_192,EncodeType.AES_CFB_PKCS5PADDING);
}
/**
* AES_CFB_192 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_CFB_192(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_192,EncodeType.AES_CFB_PKCS5PADDING);
}
/**
* AES_CFB_256加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_CFB_256(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_256,EncodeType.AES_CFB_PKCS5PADDING);
}
/**
* AES_CFB_256 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_CFB_256(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_256,EncodeType.AES_CFB_PKCS5PADDING);
}
/**
* AES_CBC_128加密
* 输入必须是16字节,不然报错 javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_CBC_128(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_128,EncodeType.AES_CBC_NOPADDING);
}
/**
* AES_CBC_128 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_CBC_128(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_128,EncodeType.AES_CBC_NOPADDING);
}
/**
* AES_CBC_192加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_CBC_192(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_192,EncodeType.AES_CBC_PKCS5PADDING);
}
/**
* AES_CBC_192 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_CBC_192(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_192,EncodeType.AES_CBC_PKCS5PADDING);
}
/**
* AES_CBC_256加密
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_CBC_256(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,getIV(),AESType.AES_256,EncodeType.AES_CBC_ISO10126PADDING);
}
/**
* AES_CBC_256 解密
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_CBC_256(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,getIV(),AESType.AES_256,EncodeType.AES_CBC_ISO10126PADDING);
}
/**
* AES_ECB_128加密(默认使用AES/ECB/PKCS5Padding)
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_ECB_128(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,null,AESType.AES_128,EncodeType.AES_DEFAULT);
}
/**
* AES_ECB_128 解密(默认使用AES/ECB/PKCS5Padding)
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_ECB_128(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,null,AESType.AES_128,EncodeType.AES_DEFAULT);
}
/**
* AES_ECB_192加密(默认使用AES/ECB/PKCS5Padding)
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_ECB_192(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,null,AESType.AES_192,EncodeType.AES_DEFAULT);
}
/**
* AES_ECB_192 解密(默认使用AES/ECB/PKCS5Padding)
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_ECB_192(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,null,AESType.AES_192,EncodeType.AES_DEFAULT);
}
/**
* AES_ECB_256加密(默认使用AES/ECB/PKCS5Padding)
* @param content 加密的字符串
* @return 加密后的字节
*/
public static byte[] encode_AES_ECB_256(String content) throws Exception{
return encryptOrdecrypt(true,content.getBytes(CHARSET),key,null,AESType.AES_256,EncodeType.AES_DEFAULT);
}
/**
* AES_ECB_256 解密(默认使用AES/ECB/PKCS5Padding)
* @param encrypt 加密后的字节
* @return 解密后的字节
*/
public static byte[] decode_AES_ECB_256(byte[] encrypt) throws Exception{
return encryptOrdecrypt(false,encrypt,key,null,AESType.AES_256,EncodeType.AES_DEFAULT);
}
/**
* 加密解密方法
* @param isEncrypt true:加密。false:解密
* @param source 源
* @param key 秘钥
* @param type 算法类型
* @param encodeType 算法/模式/填充
*/
public static byte[] encryptOrdecrypt(boolean isEncrypt, byte[] source, String key, byte[] iv, AESType type, String encodeType) throws UnsupportedEncodingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
if (isEncrypt) {
byte[] encodeByte = encryptOrDecrypt(Cipher.ENCRYPT_MODE, source, key, iv, type, encodeType);
/* String encodeStr = TypeConvert.bytesToHexString(encodeByte);
System.out.println("加密后为:" + encodeStr);*/
return encodeByte;
} else {
byte[] decodeByte = encryptOrDecrypt(Cipher.DECRYPT_MODE, source, key, iv, type, encodeType);
/*String decodeStr = new String(decodeByte, CHARSET);
System.out.println("解密后为:" + decodeStr);*/
return decodeByte;
}
}
private static byte[] encryptOrDecrypt(int mode, byte[] byteContent, String key, byte[] iv, AESType type, String modeAndPadding) throws InvalidKeyException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
//此处解决mac,linux报错
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(key.getBytes());
kgen.init(type.value, random);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec keySpec = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance(modeAndPadding);// 创建密码器
if (null != iv) {
//指定一个初始化向量 (Initialization vector,IV), IV 必须是16位
cipher.init(mode, keySpec, new IvParameterSpec(iv));
} else {
cipher.init(mode, keySpec);
}
byte[] result = cipher.doFinal(byteContent);
return result;
}
/**
* 指定一个初始化向量 (Initialization vector,IV),IV 必须是16位
*/
public static final byte[] getIV() throws Exception {
return "1234567812345678".getBytes(CHARSET);
}
}
\ No newline at end of file
package com.fedex.connect.common.dependencies.util.arithmetic;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
@Component
public class AesFieldUtils {
/**
* 加密算法
*/
private final String KEY_ALGORITHM = "AES";
/**
* 算法/模式/补码方式
*/
private final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
/**
* 编码格式
*/
private final String CODE = "utf-8";
/**
* base64验证规则
*/
private static final String BASE64_RULE = "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)=?$";
/**
* 正则验证对象
*/
private static final Pattern PATTERN = Pattern.compile(BASE64_RULE);
/**
* 加解密 密钥key
*/
private String key = "f9c338063a04b7cedf2c09ec93119e8c";
/**
* @param content 加密字符串
* @return 加密结果
*/
public String encrypt(String content) {
return encrypt(content, key);
}
/**
* 加密
*
* @param content 加密参数
* @param key 加密key
* @return 结果字符串
*/
public String encrypt(String content, String key) {
//判断如果已经是base64加密字符串则返回原字符串
if (isBase64(content)) {
return content;
}
// 为了安全起见,暂时不加密,需要时再放开
//return content;
byte[] encrypted = encrypt2bytes(content, key);
if (null == encrypted || encrypted.length < 1) {
log.error("加密字符串[{}]转字节为null", content);
return null;
}
return Base64Utils.encodeToString(encrypted);
}
/**
* @param content 加密字符串
* @param key 加密key
* @return 返回加密字节
*/
public byte[] encrypt2bytes(String content, String key) {
try {
byte[] raw = key.getBytes(CODE);
SecretKeySpec secretKeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
return cipher.doFinal(content.getBytes(CODE));
} catch (Exception e) {
log.error("failed to encrypt: {} of {}", content, e);
return null;
}
}
/**
* @param content 加密字符串
* @return 返回加密结果
*/
public String decrypt(String content) {
try {
return decrypt(content, key);
} catch (Exception e) {
log.error("failed to decrypt: {}, e: {}", content, e);
return null;
}
}
/**
* 解密
*
* @param content 解密字符串
* @param key 解密key
* @return 解密结果
*/
public String decrypt(String content, String key) throws Exception {
//不是base64格式字符串则不进行解密
if (!isBase64(content)) {
return content;
}
// 为了安全起见,暂时不加密解密,需要时再放开
//return content;
return decrypt(Base64Utils.decodeFromString(content), key);
}
/**
* @param content 解密字节
* @param key 解密key
* @return 返回解密内容
*/
public String decrypt(byte[] content, String key) throws Exception {
if (key == null) {
log.error("AES key should not be null");
return null;
}
byte[] raw = key.getBytes(CODE);
SecretKeySpec keySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, keySpec);
try {
byte[] original = cipher.doFinal(content);
return new String(original, CODE);
} catch (Exception e) {
log.error("failed to decrypt content: {}/ key: {}, e: {}", content, key, e);
return null;
}
}
/**
* 判断是否为 base64加密
*
* @param str 参数
* @return 结果
*/
public static boolean isBase64(String str) {
Matcher matcher = PATTERN.matcher(str);
return matcher.matches();
}
}
package com.fedex.connect.common.dependencies.util.arithmetic;
/**
*
*/
public class EncodeType {
/**
算法/模式/填充 字节加密后数据长度 不满16字节加密后长度
AES/CBC/NoPadding 16 不支持
AES/CBC/PKCS5Padding 32 16
AES/CBC/ISO10126Padding 32 16
AES/CFB/NoPadding 16 原始数据长度
AES/CFB/PKCS5Padding 32 16
AES/CFB/ISO10126Padding 32 16
AES/ECB/NoPadding 16 不支持
AES/ECB/PKCS5Padding 32 16
AES/ECB/ISO10126Padding 32 16
AES/OFB/NoPadding 16 原始数据长度
AES/OFB/PKCS5Padding 32 16
AES/OFB/ISO10126Padding 32 16
AES/PCBC/NoPadding 16 不支持
AES/PCBC/PKCS5Padding 32 16
AES/PCBC/ISO10126Padding 32 16
*/
//默认为 AES_CBC_PKCS5PADDING
public final static String AES_DEFAULT = "AES";
public final static String AES_CBC_NOPADDING = "AES/CBC/NoPadding";
public final static String AES_CBC_PKCS5PADDING = "AES/CBC/PKCS5Padding";
public final static String AES_CBC_ISO10126PADDING = "AES/CBC/ISO10126Padding";
public final static String AES_CFB_NOPADDING = "AES/CFB/NoPadding";
public final static String AES_CFB_PKCS5PADDING = "AES/CFB/PKCS5Padding";
public final static String AES_CFB_ISO10126PADDING = "AES/CFB/ISO10126Padding";
public final static String AES_ECB_NOPADDING = "AES/ECB/NoPadding";
public final static String AES_ECB_PKCS5PADDING = "AES/ECB/PKCS5Padding";
public final static String AES_ECB_ISO10126PADDING = "AES/ECB/ISO10126Padding";
public final static String AES_OFB_NOPADDING = "AES/OFB/NoPadding";
public final static String AES_OFB_PKCS5PADDING = "AES/OFB/PKCS5Padding";
public final static String AES_OFB_ISO10126PADDING = "AES/OFB/ISO10126Padding";
public final static String AES_PCBC_NOPADDING = "AES/PCBC/NoPadding";
public final static String AES_PCBC_PKCS5PADDING = "AES/PCBC/PKCS5Padding";
public final static String AES_PCBC_ISO10126PADDING = "AES/PCBC/ISO10126Padding";
}
......@@ -55,6 +55,8 @@ public class ConsumerWorker<K, V> implements Runnable {
if(isExpDmData(kafkaTemporaryStorage)){
//设置消息状态为待处理
kafkaTemporaryStorage.setStatus(KafkaStatusEnum.PENDING.getCode());
//将消息状态设置为已处理
kafkaTemporaryStorage.setStatusName(KafkaStatusEnum.PENDING.getName());
//设置入库时间
kafkaTemporaryStorage.setCreateTime(new Date());
//设置处理次数初始为0次
......
......@@ -2,6 +2,7 @@ package com.fedex.connect.kafka.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fedex.connect.common.dependencies.enums.sys.KafkaStatusEnum;
import com.fedex.connect.common.model.sys.KafkaStorageHistory;
import com.fedex.connect.common.model.sys.KafkaTemporaryStorage;
import com.fedex.connect.kafka.data.dto.DmProcessResults;
......@@ -118,6 +119,8 @@ public class KafkaDmServiceImpl extends BaseService implements ApplicationContex
kafkaStorageHistory.setCreateTime(new Date());
//将消息状态设置为已处理
kafkaStorageHistory.setStatus(1L);
//将消息状态设置为已处理
kafkaStorageHistory.setStatusName(KafkaStatusEnum.PROCESSED.getName());
//设置运单号
kafkaStorageHistory.setConsignmentCode(processResults.getConsignmentCode());
//保存至kafka历史表
......
......@@ -115,6 +115,9 @@ public class Dm501Util {
ceInfo.setShipperReference(dm501Consignment.getShipperReferenceNotes());
//件数
String quantity = dm501Consignment.getQuantity();
//文件或包裹
ceInfo.setDocNondocFlag(dm501Consignment.getDocNondocFlag());
if(Objects.nonNull(quantity)){
ceInfo.setPieces(Long.valueOf(quantity));
}
......@@ -197,9 +200,9 @@ public class Dm501Util {
Consignment resultConsignment = new Consignment();
BeanUtils.copyProperties(ceInfo,resultConsignment);
//运单状态赋值为"待上传"
DictionaryEntries consignmentDicEntries = cacheSystem.getDicConsignmentStatus(ConsignmentStatusEnum.CONSIGNMENT_STATUS_01.getCode());
resultConsignment.setStatusCode(consignmentDicEntries.getCode());
resultConsignment.setStatusName(consignmentDicEntries.getDescription());
// DictionaryEntries consignmentDicEntries = cacheSystem.getDicConsignmentStatus(ConsignmentStatusEnum.CONSIGNMENT_STATUS_01.getCode());
// resultConsignment.setStatusCode(consignmentDicEntries.getCode());
// resultConsignment.setStatusName(consignmentDicEntries.getEnglishName());
/**
* 初始化运单表原产国、目的国
*/
......
package com.fedex.connect.task.utils.sys;
import com.alibaba.fastjson.JSONObject;
import com.fedex.connect.common.dependencies.enums.sys.KafkaStatusEnum;
import com.fedex.connect.common.dependencies.util.JsonToJava;
import com.fedex.connect.common.dependencies.util.RPCUtils;
import com.fedex.connect.common.model.sys.KafkaStorageHistory;
......@@ -40,7 +41,9 @@ public class KafkaDmUtil {
//判断是否已经处理3次
if(kts.getFrequency().intValue() >= 3){
//标注状态为2失败
kts.setStatus(2L);
kts.setStatus(KafkaStatusEnum.PROCESSING_FAILED.getCode());
//标注状态为2失败
kts.setStatusName(KafkaStatusEnum.PROCESSING_FAILED.getName());
//备注重新处理原因
kts.setRemark((kts.getRemark() == null ? "" : kts.getRemark()) + "--->处理次数达到3次进行备份。");
backHisList.add(kts);
......