当前位置: 首页 > news >正文

网站建设行业细分网站内容编辑

网站建设行业细分,网站内容编辑,中企动力科技股份有限公司干嘛的,律师事务所网站制作问题在项目中需要对用户敏感数据进行脱敏处理,例如身份号、手机号等信息进行加密再入库。解决思路就是:一种最简单直接的方式,在所有涉及数据敏感的查询到对插入时进行密码加解密方法二:有方法一到出现对所有重大问题的影响&#…

问题

在项目中需要对用户敏感数据进行脱敏处理,例如身份号、手机号等信息进行加密再入库。

解决思路

  • 就是:一种最简单直接的方式,在所有涉及数据敏感的查询到对插入时进行密码加解密

  • 方法二:有方法一到出现对所有重大问题的影响,需要考虑到问题的出现,并且需要考虑可能出现的组员时添加数据的方法。

最后决定采用mybatis的插件在mybatis的SQL执行和结果填充操作上进行切入。上层业务调用不再需要考虑数据的加敏同时也保证了数据的加解密

Mybatis 插件原理

Mybatis 的是通过拦截器实现的,Mabatis 支持对当事人进行拦截

实现

  • 设置对参数中带有敏感参数字段的数据时进行加密

  • 对返回的结果进行解密处理

根据不同的要求,我们只需要对ParameterHandlerResultSetHandler进行切入。定义特定注解,在切入时需要检查字段中是否包含注解来是否加解密。

另外,如果你近期准备面试跳槽,建议在Java面试库小程序在线刷题,涵盖 2000+ 道 Java 面试题,几乎覆盖了所有主流技术面试题。

加注解

定义SensitiveData注解

import java.lang.annotation.*;
/*** 该注解定义在类上* 插件通过扫描类对象是否包含这个注解来决定是否继续扫描其中的字段注解* 这个注解要配合EncryptTransaction注解**/
@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveData {}

定义EncryptTransaction注解

import java.lang.annotation.*;
/*** 该注解有两种使用方式* ①:配合@SensitiveData加在类中的字段上* ②:直接在Mapper中的方法参数上使用**/
@Documented
@Inherited
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptTransaction {}

加解密工具类

解密

package sicnu.cs.ich.common.interceptor.transaction.service;public interface IDecryptUtil {/*** 解密** @param result resultType的实例* @return T* @throws IllegalAccessException 字段不可访问异常*/<T> T decrypt(T result) throws IllegalAccessException;
}

加密接口

package sicnu.cs.ich.common.interceptor.transaction.service;import java.lang.reflect.Field;public interface IEncryptUtil {/*** 加密** @param declaredFields 加密字段* @param paramsObject   对象* @param <T>            入参类型* @return 返回加密* @throws IllegalAccessException 不可访问*/<T> T encrypt(Field[] declaredFields, T paramsObject) throws IllegalAccessException;
}
package sicnu.cs.ich.common.interceptor.transaction.service.impl;
import org.springframework.stereotype.Component;
import sicnu.cs.ich.api.common.annotations.transaction.EncryptTransaction;
import sicnu.cs.ich.common.interceptor.transaction.service.IDecryptUtil;
import sicnu.cs.ich.common.util.keyCryptor.DBAESUtil;import java.lang.reflect.Field;
import java.util.Objects;@Component
public class DecryptImpl implements IDecryptUtil {/*** 解密** @param result resultType的实例*/@Overridepublic <T> T decrypt(T result) throws IllegalAccessException {//取出resultType的类Class<?> resultClass = result.getClass();Field[] declaredFields = resultClass.getDeclaredFields();for (Field field : declaredFields) {//取出所有被DecryptTransaction注解的字段EncryptTransaction encryptTransaction = field.getAnnotation(EncryptTransaction.class);if (!Objects.isNull(encryptTransaction)) {field.setAccessible(true);Object object = field.get(result);//String的解密if (object instanceof String) {String value = (String) object;//对注解的字段进行逐一解密try {field.set(result, DBAESUtil.decrypt(value));} catch (Exception e) {e.printStackTrace();}}}}return result;}
}

加密实现类

package sicnu.cs.ich.common.interceptor.transaction.service.impl;import com.fasterxml.jackson.databind.ObjectReader;
import org.springframework.stereotype.Component;
import sicnu.cs.ich.api.common.annotations.transaction.EncryptTransaction;
import sicnu.cs.ich.common.interceptor.transaction.service.IEncryptUtil;
import sicnu.cs.ich.common.util.keyCryptor.DBAESUtil;import java.io.ObjectInputStream;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Objects;
import java.util.Random;@Component
public class EncryptUtilImpl implements IEncryptUtil {@Overridepublic <T> T encrypt(Field[] declaredFields, T paramsObject) throws IllegalAccessException {//取出所有被EncryptTransaction注解的字段for (Field field : declaredFields) {EncryptTransaction encryptTransaction = field.getAnnotation(EncryptTransaction.class);if (!Objects.isNull(encryptTransaction)) {field.setAccessible(true);Object object = field.get(paramsObject);//暂时只实现String类型的加密if (object instanceof String) {String value = (String) object;//加密try {field.set(paramsObject, DBAESUtil.encrypt(value));} catch (Exception e) {e.printStackTrace();}}}}return paramsObject;}
}

模拟类

package sicnu.cs.ich.common.interceptor.transaction.service.impl;import org.springframework.stereotype.Component;
import sicnu.cs.ich.api.common.annotations.transaction.EncryptTransaction;
import sicnu.cs.ich.common.interceptor.transaction.service.IDecryptUtil;
import sicnu.cs.ich.common.util.keyCryptor.DBAESUtil;import java.lang.reflect.Field;
import java.util.Objects;@Component
public class DecryptImpl implements IDecryptUtil {/*** 解密** @param result resultType的实例*/@Overridepublic <T> T decrypt(T result) throws IllegalAccessException {//取出resultType的类Class<?> resultClass = result.getClass();Field[] declaredFields = resultClass.getDeclaredFields();for (Field field : declaredFields) {//取出所有被DecryptTransaction注解的字段EncryptTransaction encryptTransaction = field.getAnnotation(EncryptTransaction.class);if (!Objects.isNull(encryptTransaction)) {field.setAccessible(true);Object object = field.get(result);//String的解密if (object instanceof String) {String value = (String) object;//对注解的字段进行逐一解密try {field.set(result, DBAESUtil.decrypt(value));} catch (Exception e) {e.printStackTrace();}}}}return result;}
}

加解密工具类

package sicnu.cs.ich.common.util.keyCryptor;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;public class DBAESUtil {private static final String DEFAULT_V = "6859505890402435";// 自己填写private static final String KEY = "***";private static final String ALGORITHM = "AES";private static SecretKeySpec getKey() {byte[] arrBTmp = DBAESUtil.KEY.getBytes();// 创建一个空的16位字节数组(默认值为0)byte[] arrB = new byte[16];for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {arrB[i] = arrBTmp[i];}return new SecretKeySpec(arrB, ALGORITHM);}/*** 加密*/public static String encrypt(String content) throws Exception {final Base64.Encoder encoder = Base64.getEncoder();SecretKeySpec keySpec = getKey();Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");IvParameterSpec iv = new IvParameterSpec(DEFAULT_V.getBytes());cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);byte[] encrypted = cipher.doFinal(content.getBytes());return encoder.encodeToString(encrypted);}/*** 解密*/public static String decrypt(String content) throws Exception {final Base64.Decoder decoder = Base64.getDecoder();SecretKeySpec keySpec = getKey();Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");IvParameterSpec iv = new IvParameterSpec(DEFAULT_V.getBytes());cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);byte[] base64 = decoder.decode(content);byte[] original = cipher.doFinal(base64);return new String(original);}}

插件实现

参数插件ParameterInterceptor

切入mybatis设置参数时对敏感数据进行加密

Mybatis插件的使用就是通过实现Mybatis中的Interceptor接口

@Intercepts注解

// 使用mybatis插件时需要定义签名
// type标识需要切入的Handler
// method表示要要切入的方法
@Intercepts({
@Signature(type = ParameterHandler.class, method = “setParameters”, args = PreparedStatement.class),
})
package sicnu.cs.ich.common.interceptor.transaction;import com.baomidou.mybatisplus.core.MybatisParameterHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import sicnu.cs.ich.api.common.annotations.transaction.EncryptTransaction;
import sicnu.cs.ich.api.common.annotations.transaction.SensitiveData;
import sicnu.cs.ich.common.interceptor.transaction.service.IEncryptUtil;
import sicnu.cs.ich.common.util.keyCryptor.DBAESUtil;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.sql.PreparedStatement;
import java.util.*;@Slf4j
// 注入Spring
@Component
@Intercepts({@Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class),
})
public class ParameterInterceptor implements Interceptor {@Autowiredprivate IEncryptUtil IEncryptUtil;@Overridepublic Object intercept(Invocation invocation) throws Throwable {//@Signature 指定了 type= parameterHandler 后,这里的 invocation.getTarget() 便是parameterHandler//若指定ResultSetHandler ,这里则能强转为ResultSetHandlerMybatisParameterHandler parameterHandler = (MybatisParameterHandler) invocation.getTarget();// 获取参数对像,即 mapper 中 paramsType 的实例Field parameterField = parameterHandler.getClass().getDeclaredField("parameterObject");parameterField.setAccessible(true);//取出实例Object parameterObject = parameterField.get(parameterHandler);// 搜索该方法中是否有需要加密的普通字段List<String> paramNames = searchParamAnnotation(parameterHandler);if (parameterObject != null) {Class<?> parameterObjectClass = parameterObject.getClass();//对类字段进行加密//校验该实例的类是否被@SensitiveData所注解SensitiveData sensitiveData = AnnotationUtils.findAnnotation(parameterObjectClass, SensitiveData.class);if (Objects.nonNull(sensitiveData)) {//取出当前当前类所有字段,传入加密方法Field[] declaredFields = parameterObjectClass.getDeclaredFields();IEncryptUtil.encrypt(declaredFields, parameterObject);}// 对普通字段进行加密if (!CollectionUtils.isEmpty(paramNames)) {// 反射获取 BoundSql 对象,此对象包含生成的sql和sql的参数map映射Field boundSqlField = parameterHandler.getClass().getDeclaredField("boundSql");boundSqlField.setAccessible(true);BoundSql boundSql = (BoundSql) boundSqlField.get(parameterHandler);PreparedStatement ps = (PreparedStatement) invocation.getArgs()[0];// 改写参数processParam(parameterObject, paramNames);// 改写的参数设置到原parameterHandler对象parameterField.set(parameterHandler, parameterObject);parameterHandler.setParameters(ps);}}return invocation.proceed();}private void processParam(Object parameterObject, List<String> params) throws Exception {// 处理参数对象  如果是 map 且map的key 中没有 tenantId,添加到参数map中// 如果参数是bean,反射设置值if (parameterObject instanceof Map) {@SuppressWarnings("unchecked")Map<String, String> map = ((Map<String, String>) parameterObject);for (String param : params) {String value = map.get(param);map.put(param, value==null?null:DBAESUtil.encrypt(value));}
//            parameterObject = map;}}private List<String> searchParamAnnotation(ParameterHandler parameterHandler) throws NoSuchFieldException, ClassNotFoundException, IllegalAccessException {Class<MybatisParameterHandler> handlerClass = MybatisParameterHandler.class;Field mappedStatementFiled = handlerClass.getDeclaredField("mappedStatement");mappedStatementFiled.setAccessible(true);MappedStatement mappedStatement = (MappedStatement) mappedStatementFiled.get(parameterHandler);String methodName = mappedStatement.getId();Class<?> mapperClass = Class.forName(methodName.substring(0, methodName.lastIndexOf('.')));methodName = methodName.substring(methodName.lastIndexOf('.') + 1);Method[] methods = mapperClass.getDeclaredMethods();Method method = null;for (Method m : methods) {if (m.getName().equals(methodName)) {method = m;break;}}List<String> paramNames = null;if (method != null) {Annotation[][] pa = method.getParameterAnnotations();Parameter[] parameters = method.getParameters();for (int i = 0; i < pa.length; i++) {for (Annotation annotation : pa[i]) {if (annotation instanceof EncryptTransaction) {if (paramNames == null) {paramNames = new ArrayList<>();}paramNames.add(parameters[i].getName());}}}}return paramNames;}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {}
}

返回值插件ResultSetInterceptor

package sicnu.cs.ich.common.interceptor.transaction;import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import sicnu.cs.ich.api.common.annotations.transaction.SensitiveData;import java.sql.Statement;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Properties;@Slf4j
@Component
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class ResultSetInterceptor implements Interceptor {@Autowiredprivate sicnu.cs.ich.common.interceptor.transaction.service.IDecryptUtil IDecryptUtil;@Overridepublic Object intercept(Invocation invocation) throws Throwable {//取出查询的结果Object resultObject = invocation.proceed();if (Objects.isNull(resultObject)) {return null;}//基于selectListif (resultObject instanceof ArrayList) {@SuppressWarnings("unchecked")ArrayList<Objects> resultList = (ArrayList<Objects>) resultObject;if (!CollectionUtils.isEmpty(resultList) && needToDecrypt(resultList.get(0))) {for (Object result : resultList) {//逐一解密IDecryptUtil.decrypt(result);}}//基于selectOne} else {if (needToDecrypt(resultObject)) {IDecryptUtil.decrypt(resultObject);}}return resultObject;}private boolean needToDecrypt(Object object) {Class<?> objectClass = object.getClass();SensitiveData sensitiveData = AnnotationUtils.findAnnotation(objectClass, SensitiveData.class);return Objects.nonNull(sensitiveData);}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {}
}

使用

注意解在实体类上

import lombok.*;
import org.springframework.security.core.userdetails.UserDetails;
import sicnu.cs.ich.api.common.annotations.transaction.EncryptTransaction;
import sicnu.cs.ich.api.common.annotations.transaction.SensitiveData;@With
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@SensitiveData // 插件只对加了该注解的类进行扫描,只有加了这个注解的类才会生效
public class User implements Serializable {private Integer id;private String username;private String openId;private String password;// 表明对该字段进行加密@EncryptTransactionprivate String email;// 表明对该字段进行加密@EncryptTransactionprivate String mobile;private Date createTime;private Date expireTime;private Boolean status = true;
}

注解在参数上

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import sicnu.cs.ich.api.common.annotations.transaction.EncryptTransaction;@Mapper
public interface UserMapper extends BaseMapper<User> {// 只需要在参数前加上@EncryptTransaction 即可long countByEmail(@EncryptTransaction @Param("email") String email);long countByMobile(@EncryptTransaction @Param("mobile") String mobile);}

文章转载自:
http://diomed.pwrb.cn
http://shadiness.pwrb.cn
http://poplar.pwrb.cn
http://rba.pwrb.cn
http://kampuchean.pwrb.cn
http://coram.pwrb.cn
http://fruitless.pwrb.cn
http://porsche.pwrb.cn
http://fearnought.pwrb.cn
http://exterminate.pwrb.cn
http://pyrrhonism.pwrb.cn
http://baffling.pwrb.cn
http://plumply.pwrb.cn
http://aerie.pwrb.cn
http://vamplate.pwrb.cn
http://meiosis.pwrb.cn
http://telecopter.pwrb.cn
http://hypobranchial.pwrb.cn
http://dandy.pwrb.cn
http://drayage.pwrb.cn
http://sui.pwrb.cn
http://oakling.pwrb.cn
http://aristarchy.pwrb.cn
http://cypher.pwrb.cn
http://involuntarily.pwrb.cn
http://ghostwrite.pwrb.cn
http://thio.pwrb.cn
http://counterturn.pwrb.cn
http://carotic.pwrb.cn
http://slough.pwrb.cn
http://truculence.pwrb.cn
http://dissever.pwrb.cn
http://milldam.pwrb.cn
http://rassling.pwrb.cn
http://memorabilia.pwrb.cn
http://neurohormonal.pwrb.cn
http://frieda.pwrb.cn
http://bust.pwrb.cn
http://nibmar.pwrb.cn
http://acetophenetidin.pwrb.cn
http://psychic.pwrb.cn
http://abstemious.pwrb.cn
http://forgetful.pwrb.cn
http://annullable.pwrb.cn
http://aeroamphibious.pwrb.cn
http://geodesy.pwrb.cn
http://educated.pwrb.cn
http://elixir.pwrb.cn
http://ulna.pwrb.cn
http://streptococcal.pwrb.cn
http://hath.pwrb.cn
http://nerve.pwrb.cn
http://abherent.pwrb.cn
http://lampedusa.pwrb.cn
http://submarginal.pwrb.cn
http://indiscernibility.pwrb.cn
http://reconfirm.pwrb.cn
http://arthrotropic.pwrb.cn
http://doglike.pwrb.cn
http://identifiableness.pwrb.cn
http://decametre.pwrb.cn
http://butanol.pwrb.cn
http://somniloquist.pwrb.cn
http://vampire.pwrb.cn
http://spoilbank.pwrb.cn
http://oceangrapher.pwrb.cn
http://sobriquet.pwrb.cn
http://clairvoyance.pwrb.cn
http://emeerate.pwrb.cn
http://gasoline.pwrb.cn
http://croppie.pwrb.cn
http://armada.pwrb.cn
http://unphysiologic.pwrb.cn
http://resuscitate.pwrb.cn
http://indeterminably.pwrb.cn
http://fluorescein.pwrb.cn
http://hibiscus.pwrb.cn
http://monorail.pwrb.cn
http://verbify.pwrb.cn
http://ingredient.pwrb.cn
http://coneflower.pwrb.cn
http://unmeaning.pwrb.cn
http://aquaemanale.pwrb.cn
http://passerby.pwrb.cn
http://biophil.pwrb.cn
http://rockaway.pwrb.cn
http://mantis.pwrb.cn
http://pelite.pwrb.cn
http://ruefully.pwrb.cn
http://daybook.pwrb.cn
http://gigman.pwrb.cn
http://heraklid.pwrb.cn
http://conventional.pwrb.cn
http://fusibility.pwrb.cn
http://particulate.pwrb.cn
http://pinaceous.pwrb.cn
http://electrology.pwrb.cn
http://alary.pwrb.cn
http://fetterbush.pwrb.cn
http://eupepticity.pwrb.cn
http://www.dt0577.cn/news/76908.html

相关文章:

  • 软件公司网站素材万能搜索网站
  • WordPress推荐引擎网站关键词怎样优化
  • 网站开发好还要空间吗查排名
  • 做网站服装app最新新闻国内大事件
  • 烟台网站制作百度竞价推广常用到的工具
  • 婚纱摄影手机网站欣赏百度教育小程序
  • 网站建设方案后期服务广告营销是做什么的
  • 建一个网站怎么赚钱吗百度手机助手下载2021新版
  • 杭州网站制作机构网络营销常见的工具
  • 独立网站开发搜索引擎seo排名优化
  • 最专业微网站建设公司石家庄百度seo排名
  • 网站个人备案 企业备案吗单页网站制作教程
  • 蒙古文政务网站群建设工作方案网站怎么seo关键词排名优化推广
  • 网站建设的视频教程软文推广系统
  • 肥猫网站建设怎样通过网络销售自己的产品
  • 十大免费文案网站网站维护主要做什么
  • 邯郸网站建设网站开发平台推广是做什么
  • 网站建设广告背景图搜索引擎营销的主要模式
  • 网站建设和维护及云计算网络推广的工作内容
  • 货到付款网站制作外呼系统电销
  • 自己创建外贸公司优化营商环境条例
  • 咸阳网站开发公司地址建一个网站需要多少钱?
  • 学校特色网站建设情况浏阳廖主任打人
  • 大庆百度做网站多少钱百度指数api
  • 如何做整人网站线在成都网站推广公司
  • 电脑怎么建网站详细步骤福州短视频seo
  • 外贸网站建设网络公司企业营销型网站
  • 健身房网站模板网站怎样关键词排名优化
  • 呼和浩特网站建设费用今日头条新闻头条
  • pac网站代理营销最好的方法