JavaWeb信息脫敏的實現


基於實體的注解

先定義一個基於對象的脫敏注解

/**
 * 屬性脫敏注解
 *
 * @author kandw [kandw@yinhai.com]
 * @version 2019/8/28
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TaSensitive {
    /**
     * 返回脫敏字段是否帶加密文本,若是設置為true,則和返回脫敏文本時同時返回本字段的RSA加密字段
     *
     * @return
     */
    boolean withEncrypt() default false;

    /**
     * 前綴預留位數
     * 比如:
     * prefixLength=3
     * private String idCard="41234560987123543"
     * 打碼后為: idCard= 412**************
     */
    int prefixLength() default 0;

    /**
     * 后綴預留位數
     * 比如:
     * suffixLength=3
     * private String idCard="41234560987123543"
     * 打碼后為: idCard= **************543
     */
    int suffixLength() default 0;

    /**
     * 敏感字符替換字符
     * 比如: sensitiveChar="$",(suffixLength=3);
     */
    String sensitiveChar() default "*";
}

脫敏注解實現

/**
 * 數據脫敏工具
 *
 * @author kandw [kandw@yinhai.com]
 * @version 2019/8/28
 */
public class DesensitizeUtil {

    private DesensitizeUtil() {
        //empty internal constructor
    }

    /**
     * List<object> 打碼
     *
     * @param obj 需要脫敏問List集合
     * @return 返回脫敏后的數據
     */
    public static List<Object> maskListObject(List<Object> obj) {
        if (null == obj || obj.isEmpty()) {
            return Collections.emptyList();
        }
        List<Object> maskList = new ArrayList<>();
        for (Object e : obj) {
            maskObject(e);
            maskList.add(e);
        }
        return maskList;

    }

    @SuppressWarnings("unchecked")
    public static <E> E mask(E obj) {
        if (obj instanceof Collection) {
            ((Collection) obj).forEach(DesensitizeUtil::maskObject);
        } else {
            obj = maskObject(obj);
        }
        return obj;
    }

    /**
     * 字符串脫敏
     *
     * @param obj 需要脫敏的對象
     * @return 返回脫敏后的對象
     */
    public static <E> E maskObject(E obj) {
        if (null == obj) {
            return null;
        }

        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            TaSensitive annotation = field.getAnnotation(TaSensitive.class);
            //只能對字符串脫敏
            if (null == annotation || !field.getType().equals(String.class)) {
                continue;
            }

            String value = null;
            try {
                value = (String) field.get(obj);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            if (StringUtils.isEmpty(value)) {
                continue;
            }
            int suffix = annotation.suffixLength();
            int prefix = annotation.prefixLength();
            String character = annotation.sensitiveChar();
            try {
                String sensitiveStr = maskString(value, character, prefix,
                        suffix);
                //此處如果不需要可注釋
                //if (annotation.withEncrypt()) {
                    field.set(obj, JsonFactory.bean2json(new TaSensitiveBean(sensitiveStr, RSAUtils.encryptWidthEncode(value), new Format(prefix, suffix))));
                //} else {
                    field.set(obj, sensitiveStr);
                //}
            } catch (IllegalAccessException | UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }


        return obj;
    }

    /**
     * 對字符串脫敏
     *
     * @param content   需要脫敏的正文
     * @param character 脫敏后字符
     * @param prefix    預留前綴(不需要脫敏的)
     * @param suffix    預留后綴(不需要脫敏的)
     * @return 脫敏后的正文
     */
    @PostMapping
    public static String maskString(String content, String character, int prefix, int suffix) {
        if (StringUtils.isEmpty(content)) {
            return "";
        }
        String replacement = produceCharacter(content.length() - prefix - suffix, character);
        String regex = "([\\s\\S]{" + prefix + "})([\\s\\S]+)([\\s\\S]{" + suffix + "})";
        //*的數量是content.length -start-end
        return content.replaceAll(regex, "$1" + replacement + "$3");
    }

    private static String produceCharacter(int len, String character) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < len; i++) {
            sb.append(character);
        }
        return sb.toString();
    }


}

基於接口的注解

基於接口調用待補充


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM