2019-11-12

2019-11-12  本文已影响0人  YANG_ad29

springboot 接口参数统一解密
先定义一个加密注解

package com.qlt.common.annotation;

import org.springframework.web.bind.annotation.Mapping;

import java.lang.annotation.*;

/**
 * 接口解密
 * @author
 *
 */
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Mapping
@Documented
public @interface Decrypt {
    boolean decode() default true;
}

拦截处理

package com.aaa.common.config;

import com.alibaba.fastjson.JSONObject;
import com.aaa.common.annotation.Decrypt;
import com.aaa.core.web.asset.util.AESEncryption;
import org.apache.commons.io.IOUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;

@ControllerAdvice(basePackages = "com.aaa.core.api")
public class DecodeRequestBodyAdvice implements RequestBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        try {
            boolean encode = false;
            if (methodParameter.getMethod().isAnnotationPresent(Decrypt.class)) {
                Decrypt serializedField = methodParameter.getMethodAnnotation(Decrypt.class);
                encode = serializedField.decode();
            }
            if (encode) {
                return new MyHttpInputMessage(httpInputMessage);
            }
       else{
            return httpInputMessage;
        }
    }catch (Exception e) {
            e.printStackTrace();
            return httpInputMessage;

        }
    }

    @Override
    public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    }

    @Override
    public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    }
    class MyHttpInputMessage implements HttpInputMessage {
        private HttpHeaders headers;

        private InputStream body;

        public MyHttpInputMessage(HttpInputMessage inputMessage) throws Exception {
            this.headers = inputMessage.getHeaders();
            String s = IOUtils.toString(inputMessage.getBody(), "UTF-8");
            String content = JSONObject.parseObject(s).getString("content");
            if (null==content){
                throw new RuntimeException("参数【content】缺失异常!");
            }
            try{
                this.body = IOUtils.toInputStream(AESEncryption.decrypt(content, AESEncryption.PASSWORD_HOT_APP));
            }catch (Exception e){
                throw new RuntimeException("解密失败");
            }
        }

        @Override
        public InputStream getBody() throws IOException {
            return body;
        }

        @Override
        public HttpHeaders getHeaders() {
            return headers;
        }

    }


}

加解密

package com.aaa.core.web.asset.util;

import org.bitcoinj.core.Base58;
import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESEncryption {
    private static final String TAG = "";
    // /** 算法/模式/填充 **/
    private static final String CipherMode = "";//CBC
    private static final int KeyLength = 128;//128 bits
    //TODO arranged key with hot app
    public static final String PASSWORD_HOT_APP = "";
    //TODO arranged init vector with hot app
    private static final String IV_HOT_APP = "";
    public static final String WORD_KEY = "";


    private static SecretKeySpec createKey(String key) {
        byte[] data = null;
        if (key == null) {
            key = "";
        }
        StringBuffer sb = new StringBuffer(KeyLength / 8);
        sb.append(key);
        while (sb.length() < (KeyLength / 8)) {
            sb.append("0");
        }
        if (sb.length() > (KeyLength / 8)) {
            sb.setLength(KeyLength / 8);
        }

        try {
            data = sb.toString().getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return new SecretKeySpec(data, "AES");
    }

    private static SecretKeySpec createPasswordKey(String key) {
        byte[] data = null;
        try {
            data = key.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return new SecretKeySpec(data, "AES");
    }

    private static IvParameterSpec createIV(String password) {
        byte[] data = null;
        if (password == null) {
            password = "";
        }
        StringBuffer sb = new StringBuffer((KeyLength / 8));
        sb.append(password);
        while (sb.length() < (KeyLength / 8)) {
            sb.append("0");
        }
        if (sb.length() > (KeyLength / 8)) {
            sb.setLength((KeyLength / 8));
        }

        try {
            data = sb.toString().getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return new IvParameterSpec(data);
    }

    private static byte[] encrypt(byte[] content, String password, String iv) {
        try {
            SecretKeySpec key = createKey(password);
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.ENCRYPT_MODE, key, createIV(iv));
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static byte[] encrypt(byte[] content, String password) {
        try {
            SecretKeySpec key = createPasswordKey(password);
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Encrypt string return base58 string of the encrypted
     *
     * @param content
     * @param password
     * @param iv
     * @return
     */
    public static String encrypt(String content, String password, String iv) {
        byte[] data = null;
        try {
            data = content.getBytes("UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        data = encrypt(data, password, iv);

        String result = Base58.encode(data);
        return result;
    }

    public static String encrypt(String content, String password) {
        byte[] data = null;
        try {
            data = content.getBytes("UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        data = encrypt(data, password);
        String result = Base58.encode(data);
        return result;
    }

    private static byte[] decrypt(byte[] content, String password, String iv) {
        try {
            SecretKeySpec key = createKey(password);
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.DECRYPT_MODE, key, createIV(iv));
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static byte[] decrypt(byte[] content, String password) {
        try {
            SecretKeySpec key = createPasswordKey(password);
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Decrypt the base58 string of content
     *
     * @param content
     * @param password
     * @param iv
     * @return
     */
    public static String decrypt(String content, String password, String iv) {
        byte[] data = null;
        try {
            data = Base58.decode(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        data = decrypt(data, password, iv);
        if (data == null)
            return null;
        String result = null;
        try {
            result = new String(data, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String decrypt(String content, String password) {
        byte[] data = null;
        try {
            data = Base58.decode(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        data = decrypt(data, password);
        if (data == null)
            return null;
        String result = null;
        try {
            result = new String(data, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }
}

如果需要把返回值加密可以实现 RequestBodyAdvice

上一篇下一篇

猜你喜欢

热点阅读