提交 8d0aff2d authored 作者:  狄熙卜's avatar 狄熙卜

first commit

上级
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="estateplat-encrypt" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel target="8" />
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="estateplat-encrypt" options="-verbose -bootclasspath $USER_HOME$/.jdks/corretto-1.8.0_342/jre/lib/rt.jar;$USER_HOME$/.jdks/corretto-1.8.0_342/jre/lib/jce.jar" />
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="edas-oss-central" />
<option name="name" value="taobao mirror central" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
</remote-repository>
<remote-repository>
<option name="id" value="rdc-releases" />
<option name="name" value="rdc-releases" />
<option name="url" value="https://repo.rdc.aliyun.com/repository/XXXXXX/" />
</remote-repository>
<remote-repository>
<option name="id" value="nexus-releases" />
<option name="name" value="nexus-releases" />
<option name="url" value="http://dev.gtis.com.cn/nexus/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="nexus-snapshots" />
<option name="name" value="nexus-snapshots" />
<option name="url" value="http://dev.gtis.com.cn/nexus/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="rdc-snapshots" />
<option name="name" value="rdc-snapshots" />
<option name="url" value="https://repo.rdc.aliyun.com/repository/XXXXXX/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="public" />
<option name="name" value="public" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="central" />
<option name="url" value="http://dev.gtis.com.cn/nexus/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
</remote-repository>
<remote-repository>
<option name="id" value="e-iceblue" />
<option name="name" value="e-iceblue" />
<option name="url" value="http://repo.e-iceblue.cn/repository/maven-public/" />
</remote-repository>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
L
java:S3740 "/Provide the parametrized type for this generic.(81
L
java:S3740 "/Provide the parametrized type for this generic.(81
Q
java:S3740"/Provide the parametrized type for this generic.(Ǝ81
^
java:S6353!"<Use concise character class syntax '\\d' instead of '[0-9]'.(81
\ No newline at end of file
q
Asrc/main/java/cn/gtmap/bdcdj/core/encrypt/executor/CryptType.java,9\3\93c6e67ac3e71b392fd6a9e56ed4c4740b16e098

Wsrc/main/java/cn/gtmap/bdcdj/core/encrypt/adapter/decrypt/AnnotationDecryptAdapter.java,5\1\5101b9522da6c3606a74cd69926977e9672b5d0c

Rsrc/main/java/cn/gtmap/bdcdj/core/encrypt/adapter/encrypt/EmptyEncryptAdapter.java,6\7\675c948255ac11b7df0ab08c48958d7db29b5069
}
Msrc/main/java/cn/gtmap/bdcdj/core/encrypt/adapter/encrypt/EncryptAdapter.java,4\b\4b1d70bd4a4c69f45d7ebecb64e132796e6e8e61
s
Csrc/main/java/cn/gtmap/bdcdj/core/encrypt/enums/HandlerKeyEnum.java,e\1\e12bd2e491cec14408dd5f49f65cebd87bd4c7e8
n
>src/main/java/cn/gtmap/bdcdj/core/encrypt/enums/SaltsEnum.java,e\3\e33fade10ea1945506feea277e20bf8d597c1a47
w
Gsrc/main/java/cn/gtmap/bdcdj/core/encrypt/enums/SeparatorCharsEnum.java,3\5\359f63209854d44a8824ecf2d1548d4ac6d213c8
u
Esrc/main/java/cn/gtmap/bdcdj/core/encrypt/executor/CryptExecutor.java,2\7\27809efe1e69269fa5cbaa1a05945230316d439c
z
Jsrc/main/java/cn/gtmap/bdcdj/core/encrypt/executor/GmSm4CryptExecutor.java,6\6\663d8dabf4453425f723e583957659f9379d9888
s
Csrc/main/java/cn/gtmap/bdcdj/core/encrypt/handler/CryptHandler.java,1\f\1fd77becd6ce771b0e575c56a6732d35cc52e026
x
Hsrc/main/java/cn/gtmap/bdcdj/core/encrypt/handler/ArrayCryptHandler.java,a\6\a6d1fef2c0107faa3898bc68df1195b006f5a00f
z
Jsrc/main/java/cn/gtmap/bdcdj/core/encrypt/handler/CryptHandlerFactory.java,e\c\ec3bae1be17c909e3950137a960de14813685976
x
Hsrc/main/java/cn/gtmap/bdcdj/core/encrypt/handler/EmptyCryptHandler.java,d\f\df5e49ec4b4870b985594139315a6b91cb5f3c8a
w
Gsrc/main/java/cn/gtmap/bdcdj/core/encrypt/handler/ListCryptHandler.java,0\e\0e64bae61be1b22fdc9003033ae6004b9df61b83

Tsrc/main/java/cn/gtmap/bdcdj/core/encrypt/port/DecryptHttpServletRequestWrapper.java,5\e\5e860852f7cb06c88a66f878e9a53e5f81c528a8
z
Jsrc/main/java/cn/gtmap/bdcdj/core/encrypt/port/InterfaceDecryptFilter.java,2\b\2b88de7f99d8f33809cf456532e85e3f2b2f8867
s
Csrc/main/java/cn/gtmap/bdcdj/core/encrypt/CryptAdapterMatadata.java,d\1\d105fcc6311628e8873700ffcef63d1178b9fae4

Ssrc/main/java/cn/gtmap/bdcdj/core/encrypt/adapter/decrypt/CommonDecryptAdapter.java,5\8\5884a8d4ecfaae93a0d39db801b97a74b8a0151d
}
Msrc/main/java/cn/gtmap/bdcdj/core/encrypt/adapter/decrypt/DecryptAdapter.java,5\d\5d7b42c99ed8fd202ef003cacb2d4915a6448c4e

Rsrc/main/java/cn/gtmap/bdcdj/core/encrypt/adapter/decrypt/EmptyDecryptAdapter.java,d\b\db92158a99d6905d0e6da6f07c0a908a46c3e81e

Ssrc/main/java/cn/gtmap/bdcdj/core/encrypt/adapter/decrypt/SimpleDecryptAdapter.java,7\4\7464cb41bbc2e33b99ed9200f04dda7d71751403
n
>src/main/java/cn/gtmap/bdcdj/core/encrypt/utils/CryptUtil.java,8\f\8f79a61438f7bcd171ab03bb71c30a6eeeb30816

Ssrc/main/java/cn/gtmap/bdcdj/core/encrypt/adapter/encrypt/SimpleEncryptAdapter.java,c\d\cd7f5fab2486cd460f824d3849d20d2ad709e829

Wsrc/main/java/cn/gtmap/bdcdj/core/encrypt/adapter/encrypt/AnnotationEncryptAdapter.java,d\8\d8cc3f05f143aa20b2e9a312a668789e64f95683
v
Fsrc/main/java/cn/gtmap/bdcdj/core/encrypt/annotation/EncryptField.java,2\7\27a28b8788ad79e9f9454b41390a834fb547a34f
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>egov-parent</artifactId>
<groupId>com.gtis</groupId>
<version>1.1.4</version>
</parent>
<groupId>com.gtis</groupId>
<artifactId>estateplat-encrypt</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<description>不动产登记平台加解密包</description>
<properties>
<spring.version>3.2.2.RELEASE</spring.version>
<freemarker.version>2.3.20</freemarker.version>
<hibernate.version>4.2.1.Final</hibernate.version>
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
</properties>
<dependencies>
<dependency>
<groupId>com.gtis</groupId>
<artifactId>egov-common</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas-client</artifactId>
<version>2.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
<dependency>
<groupId>cn.gtmap</groupId>
<artifactId>estateplat-common</artifactId>
<version>1.2.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
</plugins>
</build>
</project>
\ No newline at end of file
package cn.gtmap.bdcdj.core.encrypt;
import cn.gtmap.bdcdj.core.encrypt.adapter.decrypt.DecryptAdapter;
import cn.gtmap.bdcdj.core.encrypt.adapter.encrypt.EncryptAdapter;
public class CryptAdapterMatadata {
private EncryptAdapter encryptAdapter;
private DecryptAdapter decryptAdapter;
public EncryptAdapter getEncryptAdapter() {
return encryptAdapter;
}
public void setEncryptAdapter(EncryptAdapter encryptAdapter) {
this.encryptAdapter = encryptAdapter;
}
public DecryptAdapter getDecryptAdapter() {
return decryptAdapter;
}
public void setDecryptAdapter(DecryptAdapter decryptAdapter) {
this.decryptAdapter = decryptAdapter;
}
public Object encrypt(Object obj,String mapid){
return encryptAdapter.doEnctypt(obj,mapid);
}
public Object decrypt(Object obj,String mapid){
return decryptAdapter.doDecrypt(obj,mapid);
}
}
package cn.gtmap.bdcdj.core.encrypt;
import cn.gtmap.bdcdj.core.encrypt.executor.CryptType;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
import java.util.Map;
public class CryptProperties {
//加解密总开关
private boolean cryptEnable;
//加解密方式
private CryptType cryptType;
private String separator;//设置加解密分隔字符,加密当遇到此分隔字符时,字符前后分别进行加密,如果不配置,会有默认的分隔字符。但是由于使用用户自定义的key之后,加密得到的字符串会包含分隔字符,所以当自定义key时,需要指定分隔符
private boolean isUserSm4KeyEnable;//是否使用用户自定义的key进行sm4加解密,如果配置为true,需还要配置以下配置:sm4Salt、sm4key、encoding
private String sm4Salt;//isUserSm4KeyEnable为true时,sm4加密时使用的salt,当isUserSm4KeyEnable不为true时,取常量而非此配置
private String sm4key;//isUserSm4KeyEnable为true时,加密使用的key,需要固定长度的字符串,否则报错
private String encoding;//isUserSm4KeyEnable为true时,使用的编码
//全局加解密字段
private List<String> globalEnableFields ;
//map中全局加解密字段的例外(在例外中不加解密)
private List<Map> globalDisableEntityFields;
//entity中全局加解密字段的例外(在例外中不加解密)
private List<Map> globalDisableMapFields;
//sql加解密字段
private List<Map> sqlFileds;
//sql仅加密字段
private List<Map> sqlEncryptFileds;
//sql仅解密字段
private List<Map> sqlDecryptFileds;
//实体加解密字段
private List<Map> entityFileds;
public CryptProperties(boolean cryptEnable) {
this.cryptEnable = cryptEnable;
}
public CryptProperties(boolean cryptEnable,CryptType cryptType) {
this.cryptEnable = cryptEnable;
this.cryptType = cryptType;
}
public boolean isUserSm4KeyEnable() {
return isUserSm4KeyEnable;
}
public void setUserSm4KeyEnable(boolean userSm4KeyEnable) {
isUserSm4KeyEnable = userSm4KeyEnable;
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public String getSm4key() {
return sm4key;
}
public void setSm4key(String sm4key) {
this.sm4key = sm4key;
}
public String getSm4Salt() {
return sm4Salt;
}
public void setSm4Salt(String sm4Salt) {
this.sm4Salt = sm4Salt;
}
public String getSeparator() {
return separator;
}
public void setSeparator(String separator) {
this.separator = separator;
}
public CryptType getCryptType() {
return cryptType;
}
public void setCryptType(CryptType cryptType) {
this.cryptType = cryptType;
}
public boolean isCryptEnable() {
return cryptEnable;
}
public void setCryptEnable(boolean cryptEnable) {
this.cryptEnable = cryptEnable;
}
public List<String> getGlobalEnableFields() {
return globalEnableFields;
}
public void setGlobalEnableFields(List<String> globalEnableFields) {
this.globalEnableFields = globalEnableFields;
}
public List<Map> getGlobalDisableEntityFields() {
return globalDisableEntityFields;
}
public void setGlobalDisableEntityFields(List<Map> globalDisableEntityFields) {
this.globalDisableEntityFields = globalDisableEntityFields;
}
public List<Map> getGlobalDisableMapFields() {
return globalDisableMapFields;
}
public void setGlobalDisableMapFields(List<Map> globalDisableMapFields) {
this.globalDisableMapFields = globalDisableMapFields;
}
public List<Map> getSqlFileds() {
return sqlFileds;
}
public void setSqlFileds(List<Map> sqlFileds) {
this.sqlFileds = sqlFileds;
}
public List<Map> getSqlEncryptFileds() {
return sqlEncryptFileds;
}
public void setSqlEncryptFileds(List<Map> sqlEncryptFileds) {
this.sqlEncryptFileds = sqlEncryptFileds;
}
public List<Map> getSqlDecryptFileds() {
return sqlDecryptFileds;
}
public void setSqlDecryptFileds(List<Map> sqlDecryptFileds) {
this.sqlDecryptFileds = sqlDecryptFileds;
}
public List<Map> getEntityFileds() {
return entityFileds;
}
public void setEntityFileds(List<Map> entityFileds) {
this.entityFileds = entityFileds;
}
public boolean isEncryptDecryptEntityField(String entityName, String fieldName) {
if(StringUtils.isAnyBlank(entityName,fieldName)){
return false;
}
if(isGlobalFields(null, entityName, fieldName)){
return true;
}else{
List<Map> entityFileds = getEntityFileds();
if(getEntityContainsField(entityFileds,entityName,fieldName)){
return true;
}else{
return false;
}
}
}
public boolean isEncryptMapField(String mapid, String fieldName) {
if(StringUtils.isAnyBlank(mapid,fieldName)){
return false;
}
if(isGlobalFields(mapid,null, fieldName)){
return true;
}else{
List<Map> sqlFileds = getSqlFileds();
List<Map> sqlEncryptFileds = getSqlEncryptFileds();
if(getMapContainsField(sqlFileds,mapid,fieldName) || getMapContainsField(sqlEncryptFileds,mapid,fieldName)){
return true;
}else{
return false;
}
}
}
public boolean isDecryptMapField(String mapid, String fieldName) {
if(StringUtils.isAnyBlank(mapid,fieldName)){
return false;
}
if(isGlobalFields(mapid,null, fieldName)){
return true;
}else{
List<Map> sqlFileds = getSqlFileds();
List<Map> sqlDecryptFileds = getSqlDecryptFileds();
if(getMapContainsField(sqlFileds,mapid,fieldName) || getMapContainsField(sqlDecryptFileds,mapid,fieldName)){
return true;
}else{
return false;
}
}
}
/**
* 判断是否是全局加解密字段
* @param fieldName
* @return
*/
private boolean isGlobalFields(String mapid,String entityName,String fieldName){
List<String> globalEnableFields = getGlobalEnableFields();
List<Map> globalDisableMapFields = getGlobalDisableMapFields();
List<Map> globalDisableEntityFields = getGlobalDisableEntityFields();
// if(CollectionUtils.isNotEmpty(globalEnableFields) && globalEnableFields.contains(fieldName)){
if(CollectionUtils.isNotEmpty(globalEnableFields) && containsIgnoreCase(globalEnableFields,fieldName)){
//是全局变量,看是map还是entity
if(StringUtils.isNotBlank(mapid) && CollectionUtils.isNotEmpty(globalDisableMapFields)){
for (Map globalDisableMapField : globalDisableMapFields) {
if(mapid.endsWith(MapUtils.getString(globalDisableMapField,"mapid"))
&& StringUtils.equalsIgnoreCase(fieldName,MapUtils.getString(globalDisableMapField,"field"))){
return false;//反向判断,暂时不抽取方法
}
}
return true;
}else if(StringUtils.isNotBlank(entityName) && CollectionUtils.isNotEmpty(globalDisableEntityFields)){
for (Map globalDisableEntityField : globalDisableEntityFields) {
if(entityName.endsWith(MapUtils.getString(globalDisableEntityField,"entity"))
&& StringUtils.equalsIgnoreCase(fieldName,MapUtils.getString(globalDisableEntityField,"field"))){
return false;//反向判断,暂时不抽取方法
}
}
return true;
}else{
return true;
}
}else{//不是全局变量,返回false
return false;
}
}
private boolean containsIgnoreCase(List<String> list,String s){
if(CollectionUtils.isNotEmpty(list)){
for (String s1 : list) {
if(StringUtils.equalsIgnoreCase(s1,s)){
return true;
}
}
return false;
}else{
return false;
}
}
private boolean getEntityContainsField(List<Map> list,String entityName,String fieldName){
if(CollectionUtils.isNotEmpty(list)){
for (Map map : list) {
if(entityName.endsWith(MapUtils.getString(map,"entity"))
&& StringUtils.equalsIgnoreCase(fieldName,MapUtils.getString(map,"field"))){
return true;
}
}
return false;
}else{
return false;
}
}
private boolean getMapContainsField(List<Map> list,String mapid,String fieldName){
if(CollectionUtils.isNotEmpty(list)){
for (Map map : list) {
if(mapid.endsWith(MapUtils.getString(map,"mapid"))
&& StringUtils.equalsIgnoreCase(fieldName,MapUtils.getString(map,"field"))){
return true;
}
}
return false;
}else{
return false;
}
}
}
package cn.gtmap.bdcdj.core.encrypt;
import cn.gtmap.bdcdj.core.encrypt.adapter.decrypt.AnnotationDecryptAdapter;
import cn.gtmap.bdcdj.core.encrypt.adapter.decrypt.CommonDecryptAdapter;
import cn.gtmap.bdcdj.core.encrypt.adapter.decrypt.DecryptAdapter;
import cn.gtmap.bdcdj.core.encrypt.adapter.decrypt.EmptyDecryptAdapter;
import cn.gtmap.bdcdj.core.encrypt.adapter.decrypt.SimpleDecryptAdapter;
import cn.gtmap.bdcdj.core.encrypt.adapter.encrypt.AnnotationEncryptAdapter;
import cn.gtmap.bdcdj.core.encrypt.adapter.encrypt.CommonEncryptAdapter;
import cn.gtmap.bdcdj.core.encrypt.adapter.encrypt.EmptyEncryptAdapter;
import cn.gtmap.bdcdj.core.encrypt.adapter.encrypt.EncryptAdapter;
import cn.gtmap.bdcdj.core.encrypt.adapter.encrypt.SimpleEncryptAdapter;
import cn.gtmap.bdcdj.core.encrypt.annotation.EncryptField;
import cn.gtmap.estateplat.core.support.mybatis.mapper.CommonMapper;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class EncryptAdapterBuilder {
private String statementId;
private Class entityClass;
private CryptProperties cryptProperties;
private Object param;
private static final EncryptAdapter EMPTY_ENCRYPT_ADAPTER = new EmptyEncryptAdapter();
private static final DecryptAdapter EMPTY_DECRYPT_ADAPTER = new EmptyDecryptAdapter();
private static final Logger LOGGER = LoggerFactory.getLogger(EncryptAdapterBuilder.class);
public EncryptAdapterBuilder(String statementId, Class entityClass, Object param, CryptProperties cryptProperties) {
this.statementId = statementId;
this.entityClass = entityClass;
this.param = param;
this.cryptProperties = cryptProperties;
}
public CryptAdapterMatadata build() {
Method method = this.getMethod();
CryptAdapterMatadata matadata = new CryptAdapterMatadata();
matadata.setEncryptAdapter(buildEncryptAdapter(method));
matadata.setDecryptAdapter(builderDecryptAdapter(method));
return matadata;
}
private EncryptAdapter buildEncryptAdapter(Method method) {
if (!cryptProperties.isCryptEnable()) {
return EMPTY_ENCRYPT_ADAPTER;
} else if (method != null && !ArrayUtils.isEmpty(method.getParameterTypes())) {
//优先确定是否是commonmapper,这种情况下不会有sql的配置,也不会有注解
if (method.getDeclaringClass().equals(CommonMapper.class)) {
return new CommonEncryptAdapter(method, cryptProperties);
} else if (hasParamEncryptAnnotation(method)) {//如果参数上有注解,将参数加密
return new AnnotationEncryptAdapter(cryptProperties);
} else if(!hasEncryptParam(method)){
return EMPTY_ENCRYPT_ADAPTER;
}else{
return new SimpleEncryptAdapter(cryptProperties);
}
} else {
return EMPTY_ENCRYPT_ADAPTER;
}
}
private DecryptAdapter builderDecryptAdapter(Method method) {
if (!cryptProperties.isCryptEnable()) {
return EMPTY_DECRYPT_ADAPTER;
} else if (method != null && method.getReturnType() != Void.class) {
if (method.getDeclaringClass().equals(CommonMapper.class)) {
return new CommonDecryptAdapter(this.entityClass, cryptProperties);
}else if(hasMethodEnctyptAnnotation(method)){
return new AnnotationDecryptAdapter(cryptProperties);
}else if(!hasDecryptReturn(method)){
return EMPTY_DECRYPT_ADAPTER;
}else{
return new SimpleDecryptAdapter(cryptProperties);
}
} else {
return EMPTY_DECRYPT_ADAPTER;
}
}
private Method getMethod() {
try {
Class clazz = Class.forName(this.statementId.substring(0, this.statementId.lastIndexOf(".")));
String methodName = this.statementId.substring(this.statementId.lastIndexOf(".") + 1);
Method[] var3 = clazz.getMethods();
int var4 = var3.length;
for (int var5 = 0; var5 < var4; ++var5) {
Method method = var3[var5];
if (method.getName().equals(methodName)) {
return method;
}
}
return null;
} catch (ClassNotFoundException var7) {
LOGGER.error("EncryptAdapterBuilder.getMethod error {}", var7);
return null;
}
}
/**
* 单一参数可以使用注解进行参数加密
* @param method
* @return
*/
private boolean hasParamEncryptAnnotation(Method method) {
Class[] parameters = method.getParameterTypes();
if (ArrayUtils.isEmpty(parameters)) {
return false;
} else {
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
//注解只对单一参数有效
if (parameterAnnotations != null && parameterAnnotations.length == 1) {
Annotation[] annotations = parameterAnnotations[0];
for (Annotation annotation : annotations) {
if (annotation != null && annotation instanceof EncryptField) {
return true;
}
}
}
return false;
}
}
/**
* 当参数只有一个,且为基本类型时,认为不需要加加密(此时需要加加密应当使用注解)
* @param method
* @return
*/
private boolean hasEncryptParam(Method method){
Class<?>[] parameterTypes = method.getParameterTypes();
if(parameterTypes != null && parameterTypes.length == 1 && parameterTypes[0] == String.class){
return false;//不需要加密 返回false
}
return true;//需要加密 返回true
}
/**
* 当返回值时string时,不能进行解密,(需要加密要添加注解)
* @param method
* @return
*/
private boolean hasDecryptReturn(Method method){
Class<?> returnType = method.getReturnType();
if(returnType != null && returnType == String.class){
return false;//不需要解密,返回false
}else{
return true;//需要解密,返回true
}
}
private boolean hasMethodEnctyptAnnotation(Method method){
EncryptField annotation = method.getAnnotation(EncryptField.class);
return annotation != null;
}
}
package cn.gtmap.bdcdj.core.encrypt;
import cn.gtmap.bdcdj.core.encrypt.executor.CryptType;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import javax.annotation.Resource;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
@Intercepts({@Signature(
type = Executor.class,
method = "update",
args = {MappedStatement.class, Object.class}
), @Signature(
type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
)})
public class EncryptInterceptor implements Interceptor {
private boolean cryptEnable;
private CryptProperties cryptProperties;
@Resource(name = "dbEncryptXmlConfig")
private DbEncryptXmlConfig dbEncryptXmlConfig;
public static final ConcurrentHashMap<String, CryptAdapterMatadata> METHOD_ENCRYPT_MAP = new ConcurrentHashMap();
@Override
public Object intercept(Invocation invocation) throws Throwable {
if (this.cryptEnable) {
String mapid = ((MappedStatement) invocation.getArgs()[0]).getId();
Object[] args = invocation.getArgs();
CryptAdapterMatadata cryptAdapterMatadata = getEncryptAdapter(args);
args[1] = cryptAdapterMatadata.encrypt(args[1],mapid);
Object returnValue = invocation.proceed();
return cryptAdapterMatadata.decrypt(returnValue,mapid);
}else{
return invocation.proceed();
}
}
public CryptAdapterMatadata getEncryptAdapter(Object[] args){
MappedStatement mappedStatement = (MappedStatement)args[0];
Class entityClass = null;
if (args[1] instanceof Map && ((Map)args[1]).containsKey("entityClass")) {
entityClass = (Class)((Map)args[1]).get("entityClass");
}
if (entityClass == null && args[1] instanceof Map && ((Map)args[1]).containsKey("record")) {
entityClass = ((Map)args[1]).get("record").getClass();
}
if (METHOD_ENCRYPT_MAP.contains(mappedStatement.getId()) && METHOD_ENCRYPT_MAP.get(mappedStatement.getId()) != null) {
return (CryptAdapterMatadata)METHOD_ENCRYPT_MAP.get(mappedStatement.getId());
} else {
EncryptAdapterBuilder encryptAdapterBuilder = new EncryptAdapterBuilder(mappedStatement.getId(), entityClass, args[1], cryptProperties);
CryptAdapterMatadata build = encryptAdapterBuilder.build();
METHOD_ENCRYPT_MAP.put(mappedStatement.getId(), build);
return build;
}
// EncryptAdapterBuilder encryptAdapterBuilder = new EncryptAdapterBuilder(mappedStatement.getId(), entityClass, args[1], cryptProperties);
// CryptAdapterMatadata build = encryptAdapterBuilder.build();
// return build;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
/**
* 从配置中初始化加解密参数
* properties中存储的是xml文件中,id="newEncryptInterceptor"的bean的props
* 只有cryptEnable(总开关) 从这个配置文件中配置
* 其余的使用dbEncryptXmlConfig类读取配置文件中的数据
* @param properties
*/
@Override
public void setProperties(Properties properties) {
this.cryptEnable = dbEncryptXmlConfig.getBooleanField("DatabaseEncryptEnable");
String cryptTypeString = dbEncryptXmlConfig.getField("CryptType");
CryptType cryptType = CryptType.valueOf(cryptTypeString);
this.cryptProperties = new CryptProperties(this.cryptEnable,cryptType);
String separator = dbEncryptXmlConfig.getField("Separator");
if(StringUtils.isNotBlank(separator)) {
this.cryptProperties.setSeparator(separator);
}
String sm4Salt = dbEncryptXmlConfig.getField("Sm4Salt");
if(StringUtils.isNotBlank(sm4Salt)){
this.cryptProperties.setSm4Salt(sm4Salt);
}
boolean userSm4KeyEnable = dbEncryptXmlConfig.getBooleanField("UserSm4KeyEnable");
this.cryptProperties.setUserSm4KeyEnable(userSm4KeyEnable);
String sm4key = dbEncryptXmlConfig.getField("Sm4key");
if(StringUtils.isNotBlank(sm4key)){
this.cryptProperties.setSm4key(sm4key);
}
String encoding = dbEncryptXmlConfig.getField("Encoding");
if(StringUtils.isNotBlank(encoding)){
this.cryptProperties.setEncoding(encoding);
}
this.cryptProperties.setGlobalEnableFields(dbEncryptXmlConfig.getGlobalEnableFields());
this.cryptProperties.setGlobalDisableEntityFields(dbEncryptXmlConfig.getGlobalDisableMapFields());
this.cryptProperties.setGlobalDisableEntityFields(dbEncryptXmlConfig.getGlobalDisableEntityFields());
this.cryptProperties.setSqlFileds(dbEncryptXmlConfig.getSqlFileds());
this.cryptProperties.setSqlEncryptFileds(dbEncryptXmlConfig.getSqlEncryptFileds());
this.cryptProperties.setSqlFileds(dbEncryptXmlConfig.getSqlFileds());
this.cryptProperties.setSqlDecryptFileds(dbEncryptXmlConfig.getSqlDecryptFileds());
this.cryptProperties.setEntityFileds(dbEncryptXmlConfig.getEntityFileds());
}
}
package cn.gtmap.bdcdj.core.encrypt;
public enum LogicalOperatorEnum {
andNotLike(" not like"),
andNotIn(" not in"),
andIn(" in"),
andLike(" like"),
andNotEqualTo(" <>"),
andEqualTo(" =");
private String operator;
private LogicalOperatorEnum(String operator) {
this.operator = operator;
}
public String getOperator() {
return this.operator;
}
}
package cn.gtmap.bdcdj.core.encrypt.adapter.decrypt;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
import cn.gtmap.bdcdj.core.encrypt.handler.CryptHandlerFactory;
public class AnnotationDecryptAdapter implements DecryptAdapter{
private CryptProperties cryptProperties;
public AnnotationDecryptAdapter(CryptProperties cryptProperties) {
this.cryptProperties = cryptProperties;
}
public Object doDecrypt(Object obj,String mapid) {
return CryptHandlerFactory.getCryptHandler(obj).decrypt(obj,cryptProperties,mapid);//实际上只有一种情况会走到这个位置:返回值时String,且使用了注解
}
}
package cn.gtmap.bdcdj.core.encrypt.adapter.decrypt;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
import cn.gtmap.bdcdj.core.encrypt.handler.CryptHandlerFactory;
import cn.gtmap.estateplat.core.support.mybatis.mapper.EntityHelper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.collections.CollectionUtils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class CommonDecryptAdapter implements DecryptAdapter{
private Class entityClass;
private CryptProperties cryptProperties;
public CommonDecryptAdapter(Class entityClass, CryptProperties cryptProperties) {
this.entityClass = entityClass;
this.cryptProperties = cryptProperties;
}
public Object doDecrypt(Object param,String mapid) {
if (this.entityClass == null || param == null || param instanceof Integer || param instanceof List && CollectionUtils.isNotEmpty((List)param) && ((List)param).get(0) instanceof Integer) {
return param;
} else if (param instanceof List) {
if (CollectionUtils.isEmpty((Collection)param)) {
return param;
}else{
List<Object> resultList = (List<Object>) EntityHelper.maplist2BeanList((List)param, this.entityClass);
Object res = CryptHandlerFactory.getCryptHandler(resultList).decrypt(resultList, cryptProperties, null);
return JSON.parseArray(JSON.toJSONString(res, new SerializerFeature[]{SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat}), Map.class);
}
}else{
return CryptHandlerFactory.getCryptHandler(EntityHelper.map2Bean((Map)param, this.entityClass)).decrypt(EntityHelper.map2Bean((Map)param, this.entityClass),cryptProperties,mapid);
}
}
}
package cn.gtmap.bdcdj.core.encrypt.adapter.decrypt;
public interface DecryptAdapter {
Object doDecrypt(Object obj,String mapid);
}
package cn.gtmap.bdcdj.core.encrypt.adapter.decrypt;
public class EmptyDecryptAdapter implements DecryptAdapter{
public Object doDecrypt(Object obj,String mapid) {
return obj;
}
}
package cn.gtmap.bdcdj.core.encrypt.adapter.decrypt;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
import cn.gtmap.bdcdj.core.encrypt.handler.CryptHandlerFactory;
public class SimpleDecryptAdapter implements DecryptAdapter{
private CryptProperties cryptProperties;
public SimpleDecryptAdapter(CryptProperties cryptProperties) {
this.cryptProperties = cryptProperties;
}
public Object doDecrypt(Object obj,String mapid) {
return CryptHandlerFactory.getCryptHandler(obj).decrypt(obj,cryptProperties,mapid);
}
}
package cn.gtmap.bdcdj.core.encrypt.adapter.encrypt;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
import cn.gtmap.bdcdj.core.encrypt.handler.CryptHandlerFactory;
public class AnnotationEncryptAdapter implements EncryptAdapter {
private CryptProperties cryptProperties;
public AnnotationEncryptAdapter(CryptProperties cryptProperties) {
this.cryptProperties = cryptProperties;
}
@Override
public Object doEnctypt(Object param,String mapid) {
//使用注解,参数一定加密(规定了只有一个参数时才使用注解)
return CryptHandlerFactory.getCryptHandler(param).encrypt(param, this.cryptProperties, mapid);
}
}
package cn.gtmap.bdcdj.core.encrypt.adapter.encrypt;
public class EmptyEncryptAdapter implements EncryptAdapter{
@Override
public Object doEnctypt(Object param,String mapid) {
return param;
}
}
package cn.gtmap.bdcdj.core.encrypt.adapter.encrypt;
public interface EncryptAdapter {
Object doEnctypt(Object param,String mapid);
}
package cn.gtmap.bdcdj.core.encrypt.adapter.encrypt;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
import cn.gtmap.bdcdj.core.encrypt.handler.CryptHandlerFactory;
public class SimpleEncryptAdapter implements EncryptAdapter {
private CryptProperties cryptProperties;
public SimpleEncryptAdapter(CryptProperties cryptProperties) {
this.cryptProperties = cryptProperties;
}
@Override
public Object doEnctypt(Object param,String mapid) {
return CryptHandlerFactory.getCryptHandler(param).encrypt(param, this.cryptProperties, mapid);
}
}
package cn.gtmap.bdcdj.core.encrypt.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.PARAMETER,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptField {
}
package cn.gtmap.bdcdj.core.encrypt.enums;
public enum HandlerKeyEnum {
EMPTY_HANDLER("EMPTY_HANDLER"),
MAP_HANDLER("MAP_HANDLER"),
STRING_HANDLER("STRING_HANDLER"),
LIST_HANDLER("LIST_HANDLER"),
BEAN_HANDLER("BEAN_HANDLER"),
ARRAY_HANDLER("ARRAY_HANDLER");
private String key;
private HandlerKeyEnum(String key) {
this.key = key;
}
public String getKey() {
return this.key;
}
}
package cn.gtmap.bdcdj.core.encrypt.enums;
public enum SaltsEnum {
SALTS("apmtg04b"),
GM_SM2_SALTS("b2a1fdd"),
GM_SM4_SALTS("4mspamtg");
private String salt;
private SaltsEnum(String salt) {
this.salt = salt;
}
public String getSalt() {
return this.salt;
}
}
package cn.gtmap.bdcdj.core.encrypt.enums;
public enum SeparatorCharsEnum {
COMMA(","),
COMMA_ZH(","),
BLANK(" "),
SLASH("/"),
DONUT("、");
private String chars;
private SeparatorCharsEnum(String chars) {
this.chars = chars;
}
public String getChars() {
return this.chars;
}
}
package cn.gtmap.bdcdj.core.encrypt.executor;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
/**
* 进行加解密实现的接口
*/
public interface CryptExecutor {
String encrypt(CryptProperties cryptProperties,String value);
String decrypt(CryptProperties cryptProperties,String value);
}
package cn.gtmap.bdcdj.core.encrypt.executor;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class CryptExecutorFactory {
private static Map<CryptType, CryptExecutor> cryptExecutorMap = new ConcurrentHashMap(4);
private static final Logger LOGGER = LoggerFactory.getLogger(CryptExecutorFactory.class);
public CryptExecutorFactory() {
}
private static void registerCryptExcutor() {
// cryptExecutorMap.put(CryptType.AES_CBC, new AesCryptExecutor());
// cryptExecutorMap.put(CryptType.GM_SM2, new GmSm2CryptExecutor());
cryptExecutorMap.put(CryptType.GM_SM4, new GmSm4CryptExecutor());
}
public static CryptExecutor getTypeHandler(CryptProperties cryptProperties) {
CryptType chooseType = cryptProperties.getCryptType();
if (cryptExecutorMap.containsKey(chooseType)) {
CryptExecutor cryptExecutor = (CryptExecutor)cryptExecutorMap.get(chooseType);
return cryptExecutor;
} else {
LOGGER.error(chooseType + "has no matched CryptExcutor");
return null;
}
}
static {
registerCryptExcutor();
}
}
package cn.gtmap.bdcdj.core.encrypt.executor;
public enum CryptType {
AES_CBC,
GM_SM2,
GM_SM4,
NULL;
private CryptType() {
}
}
package cn.gtmap.bdcdj.core.encrypt.executor;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
import cn.gtmap.bdcdj.core.encrypt.utils.CryptUtil;
import cn.gtmap.bdcdj.core.encrypt.utils.GmSm4Util;
import org.apache.commons.lang3.StringUtils;
public class GmSm4CryptExecutor implements CryptExecutor {
public GmSm4CryptExecutor() {
}
@Override
public String encrypt(CryptProperties cryptProperties, String decryptString) {
if (StringUtils.isBlank(decryptString)) {
return decryptString;
} else if (StringUtils.isNotEmpty(cryptProperties.getSm4Salt()) && StringUtils.startsWithIgnoreCase(decryptString, cryptProperties.getSm4Salt())) {
return decryptString;
} else {
String separatorChars = CryptUtil.getSeparatorChars(decryptString);
if (StringUtils.isNotEmpty(cryptProperties.getSeparator()) && !StringUtils.equalsIgnoreCase(separatorChars, cryptProperties.getSeparator())) {
separatorChars = cryptProperties.getSeparator();
}
if (!StringUtils.isNotEmpty(separatorChars)) {
return GmSm4Util.encryptEcb(decryptString, cryptProperties);
} else {
String[] paramArray = StringUtils.split(decryptString, separatorChars);
StringBuilder encryptParam = new StringBuilder();
String[] var6 = paramArray;
int var7 = paramArray.length;
for(int var8 = 0; var8 < var7; ++var8) {
String temp = var6[var8];
encryptParam.append(GmSm4Util.encryptEcb(temp, cryptProperties)).append(separatorChars);
}
return StringUtils.substring(encryptParam.toString(), 0, encryptParam.length() - 1);
}
}
}
private static boolean needDecrypt(String data,CryptProperties cryptProperties) {
if (StringUtils.isNotBlank(cryptProperties.getSm4Salt()) ) {
if(StringUtils.startsWithIgnoreCase(data, cryptProperties.getSm4Salt())){
return true;
}else{
return false;
}
} else {
return true;
}
}
@Override
public String decrypt(CryptProperties cryptProperties, String encrytString) {
if (StringUtils.isBlank(encrytString)) {
return encrytString;
} else if (!needDecrypt(encrytString, cryptProperties)) {
return encrytString;
}else{
try {
String separatorChars = cn.gtmap.sdk.mybatis.plugin.utils.CryptUtil.getSeparatorChars(encrytString);
if (StringUtils.isNotEmpty(cryptProperties.getSeparator()) && !StringUtils.equalsIgnoreCase(separatorChars, cryptProperties.getSeparator())) {
separatorChars = cryptProperties.getSeparator();
}
if (!StringUtils.isNotEmpty(separatorChars)) {
return GmSm4Util.decryptEcb(encrytString, cryptProperties);
} else {
String[] paramArray = StringUtils.split(encrytString, separatorChars);
StringBuilder decryptParam = new StringBuilder();
String[] var6 = paramArray;
int var7 = paramArray.length;
for(int var8 = 0; var8 < var7; ++var8) {
String temp = var6[var8];
decryptParam.append(GmSm4Util.decryptEcb(temp, cryptProperties)).append(separatorChars);
}
return StringUtils.substring(decryptParam.toString(), 0, decryptParam.length() - 1);
}
} catch (Exception var10) {
var10.printStackTrace();
return encrytString;
}
}
}
}
package cn.gtmap.bdcdj.core.encrypt.handler;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
/**
* 列表只需要将每个元素进行加解密,不需要获取加解密字段
*/
public class ArrayCryptHandler implements CryptHandler<Object> {
@Override
public Object encrypt(Object object, CryptProperties cryptProperties,String mapid) {
if (object == null) {
return null;
} else {
Object[] arrs = (Object[])((Object[])object);
Object[] result = new Object[arrs.length];
for(int a = 0; a < arrs.length; ++a) {
result[a] = CryptHandlerFactory.getCryptHandler(arrs[a]).encrypt(arrs[a], cryptProperties,mapid);
}
return result;
}
}
@Override
public Object decrypt(Object param, CryptProperties cryptProperties,String mapid) {
if (param == null) {
return null;
} else {
Object[] arrs = (Object[])((Object[])param);
Object[] result = new Object[arrs.length];
for(int a = 0; a < arrs.length; ++a) {
result[a] = CryptHandlerFactory.getCryptHandler(arrs[a]).decrypt(arrs[a], cryptProperties,mapid);
}
return result;
}
}
}
package cn.gtmap.bdcdj.core.encrypt.handler;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
import cn.gtmap.bdcdj.core.encrypt.DbEncryptXmlConfig;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* bean中获取加解密字段
*/
@Component
public class BeanCryptHandler implements CryptHandler<Object> {
private static final Logger LOGGER = LoggerFactory.getLogger(BeanCryptHandler.class);
@Override
public Object encrypt(Object bean, CryptProperties cryptProperties,String mapid) {
if (bean == null) {
return null;
} else {
Object result = null;
try {
result = BeanUtils.cloneBean(bean);
} catch (Exception var11) {
LOGGER.error("BeanCryptHandler.encrypt.getresult"+var11.getMessage());
}
List<Field> filedList = this.getEncryptDecryptFields(result.getClass(),cryptProperties);
if (CollectionUtils.isEmpty(filedList)) {
return bean;
} else {
for (Field field : filedList) {
try {
field.setAccessible(true);
Object o = field.get(result);
if(o != null){
Object encrypted = CryptHandlerFactory.getCryptHandler(o).encrypt(o, cryptProperties,mapid);
field.set(result,encrypted);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
LOGGER.error("BeanCryptHandler.encrypt.getfield"+e.getMessage());
}
}
return result;
}
}
}
@Override
public Object decrypt(Object param, CryptProperties cryptProperties,String mapid) {
if (param == null) {
return null;
} else {
List<Field> filedList = this.getEncryptDecryptFields(param.getClass(),cryptProperties);
if(CollectionUtils.isNotEmpty(filedList)){
for (Field field : filedList) {
try {
field.setAccessible(true);
Object o = field.get(param);
if(o != null){
Object decrypt = CryptHandlerFactory.getCryptHandler(o).decrypt(o, cryptProperties,mapid);
field.set(param,decrypt);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
LOGGER.error("BeanCryptHandler.decrypt"+e.getMessage());
}
}
}
return param;
}
}
//对bean来说,加密字段和解密字段应该一致
private List<Field> getEncryptDecryptFields(Class clazz, CryptProperties cryptProperties) {
List<Field> filedList = new ArrayList();
if (clazz == null) {
return filedList;
} else {
Field[] fields = clazz.getDeclaredFields();
String fieldName = "";
String className = clazz.getName();
if(fields != null && fields.length > 0){
for (Field field : fields) {
fieldName = field.getName();
if(cryptProperties.isEncryptDecryptEntityField(className,fieldName)){
filedList.add(field);
}
}
}
return filedList;
}
}
}
package cn.gtmap.bdcdj.core.encrypt.handler;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
public interface CryptHandler<T> {
Object encrypt(T obj, CryptProperties cryptProperties,String mapid);
Object decrypt(T obj, CryptProperties cryptProperties,String mapid);
}
package cn.gtmap.bdcdj.core.encrypt.handler;
import cn.gtmap.bdcdj.core.encrypt.enums.HandlerKeyEnum;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class CryptHandlerFactory {
private static Map<String, CryptHandler> handlerMap = new ConcurrentHashMap(6);
public CryptHandlerFactory() {
}
private static void registHandler() {
handlerMap.put(HandlerKeyEnum.EMPTY_HANDLER.getKey(), new EmptyCryptHandler());
handlerMap.put(HandlerKeyEnum.STRING_HANDLER.getKey(), new StringCryptHandler());
handlerMap.put(HandlerKeyEnum.LIST_HANDLER.getKey(), new ListCryptHandler());
handlerMap.put(HandlerKeyEnum.ARRAY_HANDLER.getKey(), new ArrayCryptHandler());
handlerMap.put(HandlerKeyEnum.BEAN_HANDLER.getKey(), new BeanCryptHandler());
handlerMap.put(HandlerKeyEnum.MAP_HANDLER.getKey(), new MapCryptHandler());
}
public static CryptHandler getCryptHandler(Object obj) {
String hanlerKey = gethandlerKey(obj);
return handlerMap.get(hanlerKey);
}
private static String gethandlerKey(Object obj) {
if (obj != null) {
if (obj instanceof String && StringUtils.isBlank((String)obj)) {
return HandlerKeyEnum.EMPTY_HANDLER.getKey();
} else if (obj instanceof Map) {
return HandlerKeyEnum.MAP_HANDLER.getKey();
} else if (obj instanceof String) {
return HandlerKeyEnum.STRING_HANDLER.getKey();
} else if (obj instanceof List) {
return HandlerKeyEnum.LIST_HANDLER.getKey();
} else {
return obj.getClass().isArray() ? HandlerKeyEnum.LIST_HANDLER.getKey() : HandlerKeyEnum.BEAN_HANDLER.getKey();
}
} else {
return HandlerKeyEnum.EMPTY_HANDLER.getKey();
}
}
static {
registHandler();
}
}
package cn.gtmap.bdcdj.core.encrypt.handler;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
/**
*
*/
public class EmptyCryptHandler implements CryptHandler<Object> {
@Override
public Object encrypt(Object param, CryptProperties var3,String mapid) {
return param;
}
@Override
public Object decrypt(Object param, CryptProperties var3,String mapid) {
return param;
}
}
package cn.gtmap.bdcdj.core.encrypt.handler;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
import org.apache.commons.collections.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
public class ListCryptHandler implements CryptHandler<Object> {
@Override
public Object encrypt(Object param, CryptProperties cryptProperties,String mapid) {
List<Object> list = (List)param;
// return this.doReturn(list) ? list : this.doEncryptList( list,cryptProperties,mapid);
return this.doEncryptList( list,cryptProperties,mapid);
}
@Override
public Object decrypt(Object param, CryptProperties cryptProperties,String mapid) {
List<Object> list = (List)param;
// if (this.doReturn(list)) {//doreturn: 在list中为基础数据类型时,不进行加解密,此处去除此逻辑
// return param;
// }else{
try{
List result = new ArrayList(list.size());
if(CollectionUtils.isNotEmpty(list)){
for (Object o : list) {
result.add(CryptHandlerFactory.getCryptHandler(o).decrypt(o, cryptProperties,mapid));
}
}
return result;
}catch (Exception e){
e.printStackTrace();
return param;
}
// }
}
public List doEncryptList( List<Object> list,CryptProperties cryptProperties,String mapid) {
List result = null;
try {
result = (List)list.getClass().newInstance();
} catch (Exception e) {
e.printStackTrace();
result = this.retryNewInstance(list);
}
try {
if(CollectionUtils.isNotEmpty(list)){
for (Object o : list) {
result.add(CryptHandlerFactory.getCryptHandler(o).encrypt(o,cryptProperties,mapid));
}
}
return result;
} catch (Exception e) {
e.printStackTrace();
return list;
}
}
private boolean doReturn(List<Object> list) {
if (CollectionUtils.isEmpty(list)) {
return true;
} else{
return (list.get(0) instanceof String || list.get(0) instanceof Integer || list.get(0) instanceof Double || list.get(0) instanceof Float);
}
}
private List retryNewInstance(List<Object> list) {
return new ArrayList();
}
}
package cn.gtmap.bdcdj.core.encrypt.handler;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.LinkedCaseInsensitiveMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class MapCryptHandler implements CryptHandler{
@Override
public Object encrypt(Object param, CryptProperties cryptProperties,String mapid) {
Map map = (Map)param;
List<String> encryptKeyList =getMapEncryptKeys(map,mapid,cryptProperties);
if(CollectionUtils.isEmpty(encryptKeyList)){
return param;
}else{
Map encryptParam = new LinkedCaseInsensitiveMap(map.size());
Set<Map.Entry> set = map.entrySet();
if(CollectionUtils.isNotEmpty(set)){
for (Map.Entry entry : set) {
String key = (String)entry.getKey();
Object value = entry.getValue();
if(encryptKeyList.contains(key.toLowerCase())){
encryptParam.put(key,CryptHandlerFactory.getCryptHandler(value).encrypt(value,cryptProperties,mapid));
}else{
encryptParam.put(key,value);
}
}
}
return encryptParam;
}
}
private List<String> getMapEncryptKeys(Map map, String mapid, CryptProperties cryptProperties) {
List<String> result = new ArrayList<String>();
if(StringUtils.isBlank(mapid)){//没有任何情况下,会有没有id的map被加密,即使是全局加解密
return result;
}else {
if (MapUtils.isNotEmpty(map)) {
Set set = map.keySet();
if(CollectionUtils.isNotEmpty(set)){
for (Object o : set) {
String key = (String) o;
if(cryptProperties.isEncryptMapField(mapid,key)){
result.add(key);
}
}
}
}
return result;
}
}
@Override
public Object decrypt(Object param, CryptProperties cryptProperties,String mapid) {
Map map = (Map)param;
List<String> decryptKeyList =getMapDecryptKeys(map,mapid,cryptProperties);
if(CollectionUtils.isEmpty(decryptKeyList)){
return param;
}else{
Map decryptParam = new LinkedCaseInsensitiveMap(map.size());
Set<Map.Entry> set = map.entrySet();
if(CollectionUtils.isNotEmpty(set)){
for (Map.Entry entry : set) {
String key = (String)entry.getKey();
Object value = entry.getValue();
if(decryptKeyList.contains(key.toLowerCase()) || decryptKeyList.contains(key)){
decryptParam.put(key,CryptHandlerFactory.getCryptHandler(value).decrypt(value,cryptProperties,mapid));
}else{
decryptParam.put(key,value);
}
}
}
return decryptParam;
}
}
private List<String> getMapDecryptKeys(Map map, String mapid, CryptProperties cryptProperties) {
List<String> result = new ArrayList<String>();
if(StringUtils.isBlank(mapid)){//没有任何情况下,会有没有id的map被加密,即使是全局加解密
return result;
}else {
if (MapUtils.isNotEmpty(map)) {
Set set = map.keySet();
if(CollectionUtils.isNotEmpty(set)){
for (Object o : set) {
String key = (String) o;
if(cryptProperties.isDecryptMapField(mapid,key)){
result.add(key);
}
}
}
}
return result;
}
}
}
package cn.gtmap.bdcdj.core.encrypt.handler;
import cn.gtmap.bdcdj.core.encrypt.CryptProperties;
import cn.gtmap.bdcdj.core.encrypt.executor.CryptExecutorFactory;
/**
* 到这个处理器的,都是需要加解密操作的
*/
public class StringCryptHandler implements CryptHandler<String>{
@Override
public Object encrypt(String param, CryptProperties crypt,String mapid) {
return CryptExecutorFactory.getTypeHandler(crypt).encrypt( crypt,param);
}
@Override
public Object decrypt(String param, CryptProperties crypt,String mapid) {
return CryptExecutorFactory.getTypeHandler(crypt).decrypt( crypt,param);
}
}
package cn.gtmap.bdcdj.core.encrypt.port;
import cn.gtmap.bdcdj.core.encrypt.DbEncryptXmlConfig;
import cn.gtmap.bdcdj.core.encrypt.utils.GmSm2Util;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.util.UrlPathHelper;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* 使用HttpServletRequestWrapper包装,后续处理时,返回新的body
*/
public class DecryptHttpServletRequestWrapper extends HttpServletRequestWrapper {
private UrlPathHelper urlPathHelper = new UrlPathHelper();
//保存流中的数据request.getInputStream()中的数据
private String body;
public DecryptHttpServletRequestWrapper(HttpServletRequest request,DbEncryptXmlConfig dbEncryptXmlConfig)
throws Exception {
super(request);
//从流中获取数据
this.body=IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
if(StringUtils.isEmpty(body)) {
body = "";
}else{
//解密报文体先存起来,后面重新放入
String path = urlPathHelper.getLookupPathForRequest(request);
List<String> interfaceEncryptList = dbEncryptXmlConfig.getInterfaceEncryptList();
String decodeKey = dbEncryptXmlConfig.getInterfaceSm2DecodeKey();
if(isNeedDecrypt(path,interfaceEncryptList)) {
body = GmSm2Util.decrypt(body, decodeKey, "");
}
}
}
@Override
public ServletInputStream getInputStream() throws IOException {
// 必须指定utf-8编码,否则json请求数据中如果包含中文,会出现异常
final ByteArrayInputStream byteArrayInputStream =
new ByteArrayInputStream(body.getBytes("utf-8"));
ServletInputStream servletInputStream = new ServletInputStream() {
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
private boolean isNeedDecrypt(String path,List<String> interfaceEncryptList) {
boolean result = false;
if(StringUtils.isNotBlank(path) && CollectionUtils.isNotEmpty(interfaceEncryptList)){
PathMatcher pathMatcher = new AntPathMatcher();
for (String pattern : interfaceEncryptList) {
if(pathMatcher.match(pattern, path)){
result = true;
break;
}
}
}
return result;
}
}
\ No newline at end of file
package cn.gtmap.bdcdj.core.encrypt.port;
import cn.gtmap.bdcdj.core.encrypt.DbEncryptXmlConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class InterfaceDecryptFilter implements Filter {
private DbEncryptXmlConfig dbEncryptXmlConfig;
public void setDbEncryptXmlConfig(DbEncryptXmlConfig dbEncryptXmlConfig) {
this.dbEncryptXmlConfig = dbEncryptXmlConfig;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//filter中无法进行注入,需要从上下文中获取
ServletContext context = filterConfig.getServletContext();
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context);
dbEncryptXmlConfig = (DbEncryptXmlConfig) ctx.getBean("dbEncryptXmlConfig");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if(dbEncryptXmlConfig.getBooleanField("InterfaceDecryptEnable")) {
try {
DecryptHttpServletRequestWrapper requestWrapper =
new DecryptHttpServletRequestWrapper((HttpServletRequest) request, dbEncryptXmlConfig);
chain.doFilter(requestWrapper, response);
} catch (Exception e) {
throw new ServletException();
}
}else{
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
}
}
package cn.gtmap.bdcdj.core.encrypt.port;
import cn.gtmap.bdcdj.core.encrypt.DbEncryptXmlConfig;
import cn.gtmap.bdcdj.core.encrypt.utils.GmSm2Util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.UrlPathHelper;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.util.List;
public class InterfaceEcnryptAspect {
Logger logger = LoggerFactory.getLogger(InterfaceEcnryptAspect.class);
private UrlPathHelper urlPathHelper = new UrlPathHelper();
@Resource(name = "dbEncryptXmlConfig")
private DbEncryptXmlConfig dbEncryptXmlConfig;
private boolean cryptEnable;
public boolean isCryptEnable() {
return cryptEnable;
}
public void setCryptEnable(boolean cryptEnable) {
this.cryptEnable = cryptEnable;
}
public Object aroundExecute(ProceedingJoinPoint joinPoint) throws Throwable{
Object returnObj = null;
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(requestAttributes != null && dbEncryptXmlConfig.getBooleanField("InterfaceEncryptEnable")) {
List<String> interfaceEncryptList = dbEncryptXmlConfig.getInterfaceEncryptList();
HttpServletRequest request = requestAttributes.getRequest();
String path = urlPathHelper.getLookupPathForRequest(request);
String declaringTypeName = joinPoint.getSignature().getDeclaringTypeName();
if(isNeedDecrypt(path,interfaceEncryptList)) {//
returnObj = joinPoint.proceed();
if(logger.isDebugEnabled()) {
logger.debug("result : " + JSON.toJSONString(returnObj));
}
String encodeKey = dbEncryptXmlConfig.getInterfaceSm2EncodeKey();
if(StringUtils.isNotBlank(encodeKey) && isController(declaringTypeName)){
String res = GmSm2Util.encrypt(JSON.toJSONString(returnObj), encodeKey, "");
if (returnObj instanceof JSONObject) {//登记程序中,只使用了fastjson的jsonobj
JSONObject jsonObject = new JSONObject();
jsonObject.put("result",res);
returnObj = jsonObject;
}else if(returnObj instanceof String){//可以将返回值为jsonobject的,或者string的加解密成本身的结构并返回,其他结构无法做到
returnObj = res;
}
logger.debug("result after encrypt: " + JSON.toJSONString(returnObj));
}
}else{
returnObj = joinPoint.proceed();
}
}else{
returnObj = joinPoint.proceed();
}
return returnObj;
}
private boolean isNeedDecrypt(String path,List<String> interfaceEncryptList) {
boolean result = false;
if(StringUtils.isNotBlank(path) && CollectionUtils.isNotEmpty(interfaceEncryptList)){
PathMatcher pathMatcher = new AntPathMatcher();
for (String pattern : interfaceEncryptList) {
if(pathMatcher.match(pattern, path)){
result = true;
break;
}
}
}
return result;
}
private boolean isController(String declaringTypeName){
boolean result = false;
if(StringUtils.isNotBlank(declaringTypeName)){
Class<?> clazz = null;
try {
clazz = Class.forName(declaringTypeName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if(clazz != null){
Annotation[] annotations = clazz.getAnnotations();
if(annotations != null && annotations.length > 0){
for (Annotation annotation : annotations) {
String name = annotation.annotationType().getName();
if(StringUtils.isNotBlank(name) && name.contains("Controller")){
result = true;
break;
}
}
}
}
}
return result;
}
}
package cn.gtmap.bdcdj.core.encrypt.utils;
import cn.gtmap.bdcdj.core.encrypt.enums.SaltsEnum;
import cn.gtmap.bdcdj.core.encrypt.enums.SeparatorCharsEnum;
import org.apache.commons.lang3.StringUtils;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
public class CryptUtil {
private static final Set<Class> IGNORE_CLASS = new HashSet();
private CryptUtil() {
}
public static boolean inIgnoreClass(Class cls) {
return IGNORE_CLASS.contains(cls);
}
public static boolean matchHex(String param) {
if (StringUtils.isBlank(param)) {
return false;
} else if (contsiansSalt(param)) {
return true;
} else {
String zjhPattern = "\\d{17}[0-9Xx]|\\d{15}";
boolean matzjh = Pattern.matches(zjhPattern, param);
if (matzjh) {
return false;
} else {
String numberPattern = "[0-9]\\d*";
boolean matchNumber = Pattern.matches(numberPattern, param);
if (matchNumber) {
return false;
} else if (param.length() % 4 != 0) {
return false;
} else {
String pattern = "^[0-9a-f]+$";
return Pattern.matches(pattern, param);
}
}
}
}
private static boolean contsiansSalt(String param) {
SaltsEnum[] var1 = SaltsEnum.values();
int var2 = var1.length;
for(int var3 = 0; var3 < var2; ++var3) {
SaltsEnum saltsEnum = var1[var3];
if (StringUtils.startsWithIgnoreCase(param, saltsEnum.getSalt())) {
return true;
}
}
return false;
}
public static String getSeparatorChars(String param) {
if (StringUtils.isBlank(param)) {
return SeparatorCharsEnum.COMMA.getChars();
} else if (StringUtils.contains(param, SeparatorCharsEnum.COMMA.getChars())) {
return SeparatorCharsEnum.COMMA.getChars();
} else if (StringUtils.contains(param, SeparatorCharsEnum.SLASH.getChars())) {
return SeparatorCharsEnum.SLASH.getChars();
} else if (StringUtils.contains(param.trim(), SeparatorCharsEnum.BLANK.getChars())) {
return SeparatorCharsEnum.BLANK.getChars();
} else {
return StringUtils.contains(param, SeparatorCharsEnum.DONUT.getChars()) ? SeparatorCharsEnum.DONUT.getChars() : "";
}
}
static {
IGNORE_CLASS.add(Byte.class);
IGNORE_CLASS.add(Short.class);
IGNORE_CLASS.add(Integer.class);
IGNORE_CLASS.add(Long.class);
IGNORE_CLASS.add(Float.class);
IGNORE_CLASS.add(Double.class);
IGNORE_CLASS.add(Boolean.class);
IGNORE_CLASS.add(Character.class);
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论