【參數(shù)加密】前后端分離請(qǐng)求參數(shù)加密與響應(yīng)結(jié)果加密處理

對(duì)于安全性要求的加強(qiáng),避免出現(xiàn)篡改請(qǐng)求結(jié)果問(wèn)題的出現(xiàn)柴钻,現(xiàn)對(duì)系統(tǒng)中所有的請(qǐng)求和結(jié)果響應(yīng)進(jìn)行加密處理。系統(tǒng)使用前后端分離設(shè)計(jì)架構(gòu),同時(shí)前端部分有Vue 項(xiàng)目也有 jQuery 項(xiàng)目饺饭。
遇到坑最多的地方是Axios 的get方式與jQuery的get方式

Java 后臺(tái)處理

  • 定義 request Filter CustomRequestFilter 處理請(qǐng)求參數(shù),攔截所有請(qǐng)求進(jìn)行解密
/**
 * 請(qǐng)求攔截器 -- 處理參數(shù)解密
 *
 * @author miniy
 */
@Setter
public class CustomRequestFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        ParameterRequestWrapper request = new ParameterRequestWrapper(req);
        filterChain.doFilter(request, servletResponse);
    }
}
  • 定義代理類處理參數(shù)

/**
 * 請(qǐng)求代理類
 *
 * @author miniy
 */
public class ParameterRequestWrapper extends HttpServletRequestWrapper {

    private byte[] body;
    private Map<String, String[]> params;

    public ParameterRequestWrapper(HttpServletRequest request) {
        super(request);
        String method = request.getMethod();
        if (method.toUpperCase().equals("GET")) {
            params = HttpHelper.getParamMap(request);
        } else {
            body = HttpHelper.getBodyString(request).getBytes(Charset.forName("UTF-8"));
        }

    }

    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() {

        final ByteArrayInputStream bais = new ByteArrayInputStream(body);

        return new ServletInputStream() {

            @Override
            public int read() throws IOException {
                return bais.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {

            }

        };
    }

    @Override
    public String getParameter(String name) {
        String[] values = params.get(name);
        if (values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }

    @Override
    public Enumeration<String> getParameterNames() {
        Vector<String> v = new Vector<>();
        Set<Map.Entry<String, String[]>> entrySet = params.entrySet();
        for (Map.Entry<String, String[]> entry : entrySet) {
            v.add(entry.getKey());
        }
        Enumeration<String> en = v.elements();
        return v.elements();
    }

    @Override
    public String[] getParameterValues(String name) {
        return params.get(name);
    }
}
  • 注冊(cè)Filter 到spring security,注冊(cè)為最外層Filter职车,攔截所有請(qǐng)求 此實(shí)現(xiàn)方式存在問(wèn)題瘫俊,將自定義Filter 注冊(cè)到spring security 中,spring security ignoring 后的url不會(huì)被過(guò)濾器攔截悴灵,改為spring注冊(cè)

    image.png

  • 提供參數(shù)處理工具類

/**
 * 工具類
 */
@Slf4j
public class HttpHelper {

    /**
     * 處理 post 請(qǐng)求體參數(shù)
     *
     * @param request
     * @return
     */
    public static String getBodyString(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        String result = "";

        try (InputStream inputStream = request.getInputStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")))) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            result = sb.toString();
            if (!StrUtils.isEmpty(result)) {
                // 數(shù)據(jù)處理
                String[] split = result.split(";");
                String ras = split[0];
                // 解密
                Map<String, Object> map = YamlUtil.builder("application-config.yml");
                Map<String, Object> sys = (Map<String, Object>) map.get("sys");
                Map<String, String> requestKey = (Map<String, String>) sys.get("requestKey");
                String privateKey = requestKey.get("privateKey");
                String publicKey = requestKey.get("publicKey");
                RSA rsa = SecureUtil.rsa(privateKey, publicKey);
                byte[] decrypt = rsa.decrypt(ras, KeyType.PrivateKey);
                // todo 如果中文亂碼扛芽,前臺(tái)需要使用URL encode 加密 此處使用decode 解密
                String keyIV = IOUtils.toString(decrypt, "utf-8");
                String[] aesAttr = keyIV.split(";");
                String key = aesAttr[0];
                String iv = aesAttr[1];
                request.setAttribute("aesKey", key);
                request.setAttribute("aesIv", iv);

                if (split.length > 1) {
                    String bodyData = split[1];
                    AES aes = new AES(Mode.CBC, Padding.ZeroPadding, key.getBytes());
                    aes.setIv(new IvParameterSpec(iv.getBytes()));
                    result = aes.decryptStr(bodyData);
                }
            }

            result = xssBaseLeach(result);
            if (!isPassUrl(request.getRequestURI())) {
                // xss sql 過(guò)濾
                result = xssSqlLeach(result);
            }
        } catch (IOException e) {
            log.error(e.toString());
        }
        return result;
    }

    /**
     * 處理 get 方式請(qǐng)求參數(shù)
     *
     * @param request
     * @return
     */
    public static Map<String, String[]> getParamMap(HttpServletRequest request) {
        HashMap<String, String[]> hashMap = new HashMap<>();

        String result;
        try {
            result = request.getQueryString();
            String regex = "params=";
            if (result.indexOf(regex) > -1) {
                // 解決+ 號(hào)變成空格的處理
                result = result.replace(regex, "").replace("+", "%2B");
                result = URLUtil.decode(result);
            }
            String[] split = result.split(";");
            String ras = split[0];
            // 解密
            Map<String, Object> map = YamlUtil.builder("application-config.yml");
            Map<String, Object> sys = (Map<String, Object>) map.get("sys");
            Map<String, String> requestKey = (Map<String, String>) sys.get("requestKey");
            String privateKey = requestKey.get("privateKey");
            String publicKey = requestKey.get("publicKey");
            RSA rsa = SecureUtil.rsa(privateKey, publicKey);
            byte[] decrypt = rsa.decrypt(ras, KeyType.PrivateKey);
            // todo 如果中文亂碼,前臺(tái)需要使用URL encode 加密 此處使用decode 解密
            String keyIV = IOUtils.toString(decrypt, "utf-8");
            String[] aesAttr = keyIV.split(";");
            String key = aesAttr[0];
            String iv = aesAttr[1];
            request.setAttribute("aesKey", key);
            request.setAttribute("aesIv", iv);
            if (split.length > 1) {
                String bodyData = split[1];
                AES aes = new AES(Mode.CBC, Padding.ZeroPadding, key.getBytes());
                aes.setIv(new IvParameterSpec(iv.getBytes()));
                result = aes.decryptStr(bodyData);
                //xss sql 注入處理
                result = xssBaseLeach(result);
                if (!isPassUrl(request.getRequestURI())) {
                    // xss sql 過(guò)濾
                    result = xssSqlLeach(result);
                }

                Map<String, Object> toMap = JSONUtils.jsonObjToMap(JSONUtils.ToJsonObj(result));
                for (String mapKey : toMap.keySet()) {
                    hashMap.put(mapKey, new String[]{toMap.get(mapKey).toString()});
                }
            }

        } catch (IOException e) {
            log.error(e.toString());
        }
        return hashMap;
    }

    /**
     * 過(guò)濾 參數(shù)中存在的 js 代碼
     *
     * @param body
     * @return
     */
    private static String xssBaseLeach(String body) {
        return HtmlUtils.removeHtmlTag(body, "script");
    }

    /**
     * xss 字符替換
     *
     * @param body
     * @return
     */
    private static String xssSqlLeach(String body) {

        if (body == null || body.isEmpty()) {
            return body;
        }
        StringBuilder sb = new StringBuilder(body.length());
        for (int i = 0; i < body.length(); i++) {
            char c = body.charAt(i);
            switch (c) {
                case '>':
                    sb.append("》");// 轉(zhuǎn)義大于號(hào)
                    break;
                case '<':
                    sb.append("《");// 轉(zhuǎn)義小于號(hào)
                    break;
                case '\'':
                    sb.append("‘");// 轉(zhuǎn)義單引號(hào)
                    break;
                case '\"':
                    sb.append('"');// 轉(zhuǎn)義雙引號(hào)
                    break;
                case '&':
                    sb.append("&");// 轉(zhuǎn)義&
                    break;
                default:
                    String s1 = c + "";
                    String s = s1.replaceAll(".*([';]+|(--)+).*", "");
                    sb.append(s);
                    break;
            }

        }
        return sb.toString();
    }

    private static boolean isPassUrl(String url) {
        Map<String, Object> map = YamlUtil.builder("application-config.yml");
        Map<String, Object> sys = (Map<String, Object>) map.get("sys");
        List<String> whitelist = (List<String>) sys.get("xssList");
        return whitelist.contains(url);
    }

}
  • 定義 response Filter 攔截所有響應(yīng)結(jié)果

/**
 * 響應(yīng)攔截器 -- 處理參數(shù)加密
 *
 * @author miniy
 */
public class CustomResponseFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletResponse res = (HttpServletResponse) response;
        ResultResponseWrapper responseWrapper = new ResultResponseWrapper(res);
        chain.doFilter(request, responseWrapper);
        byte[] content = responseWrapper.getContent();
        if (content.length > 0) {
            // 響應(yīng)結(jié)果解密
            String json = IOUtils.toString(content, "utf-8");
            ResponseUtil.out((HttpServletRequest) request, (HttpServletResponse) response, JSONUtils.ToJsonObj(json));
        }
    }
}
  • 定義代理類

/**
 * 響應(yīng)代理類
 *
 * @author miniy
 */
public class ResultResponseWrapper extends HttpServletResponseWrapper {

    private ByteArrayOutputStream buffer;
    private ServletOutputStream outputStream;

    public ResultResponseWrapper(HttpServletResponse response) {
        super(response);

        buffer = new ByteArrayOutputStream();
        outputStream = new WrapperOutputStream(buffer);
    }

    @Override
    public ServletOutputStream getOutputStream() {
        return outputStream;
    }

    @Override
    public void flushBuffer() throws IOException {
        if (null != outputStream) {
            outputStream.flush();
        }
    }

    public byte[] getContent()
            throws IOException {
        flushBuffer();
        return buffer.toByteArray();
    }

    class WrapperOutputStream extends ServletOutputStream {
        private ByteArrayOutputStream bos;

        public WrapperOutputStream(ByteArrayOutputStream bos) {
            this.bos = bos;
        }

        @Override
        public void write(int b)
                throws IOException {
            bos.write(b);
        }

        @Override
        public boolean isReady() {

            // TODO Auto-generated method stub
            return false;

        }

        @Override
        public void setWriteListener(WriteListener arg0) {
            // TODO Auto-generated method stub

        }
    }

}
  • ~~注冊(cè)過(guò)濾器 1. spring security 最后一個(gè)過(guò)濾器 ~~此實(shí)現(xiàn)方式存在問(wèn)題积瞒,將自定義Filter 注冊(cè)到spring security 中川尖,spring security ignoring 后的url不會(huì)被過(guò)濾器攔截,改為spring注冊(cè)


    image.png
  • 提供工具類
/**
 * 響應(yīng)加密工具類
 */
@Slf4j
public class ResponseUtil {

    public static void out(HttpServletRequest request, HttpServletResponse response, Object json) {
        try {
            // 響應(yīng)結(jié)果加密
            // 方式1 aes 加密返回
            String key = (String) request.getAttribute("aesKey");
            String iv = (String) request.getAttribute("aesIv");
            AES aes = new AES(Mode.CBC, Padding.ZeroPadding, key.getBytes());
            aes.setIv(new IvParameterSpec(iv.getBytes()));
            String data = JSON.toJSONString(json);
            String result = aes.encryptBase64(data);

            // 方式2 rsa 加密返回
         /*   Map<String, Object> map = YamlUtil.builder("application-config.yml");
            Map<String, Object> sys = (Map<String, Object>) map.get("sys");
            Map<String, String> requestKey = (Map<String, String>) sys.get("responseKey");
            String privateKey = requestKey.get("privateKey");
            String publicKey = requestKey.get("publicKey");
            RSA rsa = SecureUtil.rsa(privateKey, publicKey);
            String data = JSON.toJSONString(json);
            // 防止中文亂碼先進(jìn)行 data url 編碼
            String encode = URLUtil.encode(data);
            String result = rsa.encryptBase64(encode, KeyType.PublicKey);*/

            response.setContentType("text/html;charset=utf-8");
            response.setHeader("Content-type", "application/json;charset=utf-8");
            response.setStatus(HttpServletResponse.SC_OK);
            response.getWriter().print(result);
        } catch (java.io.IOException e) {
            log.error(e.toString());
        }
    }
}

編輯更改過(guò)濾器的注冊(cè)
因注冊(cè)到spring security 組件上無(wú)法攔截ignoing 的請(qǐng)求茫孔,更改為spring boot 方式注冊(cè)空厌,注意點(diǎn)為order 排序的設(shè)置庐船,響應(yīng)最簡(jiǎn)單設(shè)置為最大就好。關(guān)鍵點(diǎn)是請(qǐng)求filter的位置非常重要嘲更。這里要放在 spring security 內(nèi)置過(guò)濾器前,spring CorsFilter 之后筐钟,此處多次測(cè)試猜的數(shù)為-100,暫未找到更科學(xué)方法赋朦。

   @Bean
    public FilterRegistrationBean requestFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new CustomRequestFilter());
        registration.addUrlPatterns("/*");
//        registration.setOrder(Integer.MIN_VALUE);
        registration.setOrder(-100);
        registration.setName("requestFilter");
        return registration;
    }

    @Bean
    public FilterRegistrationBean responseFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new CustomResponseFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(Integer.MAX_VALUE);
        registration.setName("responseFilter");
        return registration;
    }

JsonUtils 工具類

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.util.List;
import java.util.Map;

/**
 * json 處理工具類
 */
public class JSONUtils {

    public static JSONObject parseObj(Object object) {
        return JSONUtil.parseObj(object);
    }

    /**
     * 字符串轉(zhuǎn)JSONArray
     *
     * @param json
     * @return
     */
    public static JSONArray toJsonList(String json) {
        return JSON.parseArray(json);
    }


    /**
     * 對(duì)象轉(zhuǎn)化為字符串
     *
     * @param obj
     * @return
     */
    public static String JsonToString(Object obj) {
        return JSON.toJSONString(obj);
    }

    /**
     * 帶類型信息的轉(zhuǎn)json串
     *
     * @param obj
     * @return
     */
    public static String JsonToStringAndType(Object obj) {
        return JSON.toJSONString(obj, SerializerFeature.WriteClassName);
    }

    /**
     * Json 字符串轉(zhuǎn)為 JSONObject
     * JSONObject 對(duì)象類似Map
     * 直接通過(guò)get()方法 獲取對(duì)象
     *
     * @return
     */
    public static com.alibaba.fastjson.JSONObject ToJsonObj(String json) {
        return JSON.parseObject(json);
    }

    public static cn.hutool.json.JSONObject ToJsonObj(Object obj) {
        return JSONUtil.parseObj(obj);
    }

    /**
     * map 轉(zhuǎn) Bean
     *
     * @param map
     * @param beanClass
     * @param <T>
     * @return
     */
    public static <T> Object toBean(Map map, Class<T> beanClass) {
        return JSONUtil.toBean(JSONUtil.parseFromMap(map), beanClass, true);
    }

    public static <T> Object toBean(com.alibaba.fastjson.JSONObject jsonObject, Class<T> beanClass) {
        return JSONUtil.toBean(JSONUtil.parseObj(jsonObject.toJSONString()), beanClass, true);
    }


    /**
     * JsonArray轉(zhuǎn)java的List
     *
     * @param jsonArray
     * @param c
     * @return
     */
    public static List JSONArrayToList(JSONArray jsonArray, Class c) {
        String string = com.alibaba.fastjson.JSONObject.toJSONString(jsonArray, SerializerFeature.WriteClassName);
        List list = com.alibaba.fastjson.JSONObject.parseArray(string, c);
        return list;
    }

    public static Map jsonObjToMap(com.alibaba.fastjson.JSONObject jsonObject) {
        return JSONUtil.toBean(JSONUtil.parseObj(jsonObject.toJSONString()), Map.class);
    }

}

Java結(jié)束

前端處理

  • jQuery
    引入CryptoJS與jsencrypt支持
view.ajaxFilter = function () {

      var ajax = $.ajax;//  修改ajax方法的默認(rèn)實(shí)現(xiàn)
      $.ajax = function (options) {
          // aes 數(shù)據(jù)加密
          var u32 = uuid(32);
          var u16 = uuid(16);
          var key = CryptoJS.enc.Latin1.parse(u32);
          var iv = CryptoJS.enc.Latin1.parse(u16);

          if (options.type == 'get' || options.type == 'GET') {
              if (options.url.indexOf('?') > -1) {
                  var split = options.url.split('?');
                  var params = split[1];
                  var paramObj = params.split("&");
                  for (var i = 0; i < paramObj.length; i++) {
                      options.data[paramObj[i].split("=")[0]] = unescape(paramObj[i].split("=")[1]);
                  }
                  options.url = split[0];
              }
          }
          // data加密
          if (typeof options.data == 'object') {
              options.data = JSON.stringify(options.data);
          }

          var encrypted = CryptoJS.AES.encrypt(options.data, key, {
              iv: iv,
              mode: CryptoJS.mode.CBC,
              padding: CryptoJS.pad.ZeroPadding
          });
          // ras 數(shù)據(jù)加密
          var publicKey = ' 11';
          jsencrypt = new JSEncrypt();
          jsencrypt.setPublicKey(publicKey);
          // todo 如果中文亂碼篓冲,前臺(tái)需要使用URL encode 加密 此處使用decode 解密
          var ras = jsencrypt.encrypt(u32 + ";" + u16);

          options.data = ras + ";" + encrypted.toString();


          var dataFilter = options.dataFilter;    //  對(duì)用戶配置的success方法進(jìn)行代理  
          function ns(datas, type) {
              // 數(shù)據(jù)解密
              // 方式1 aes 解密
              var decrypt = CryptoJS.AES.decrypt(datas, key, {
                  iv: iv,
                  mode: CryptoJS.mode.CBC,
                  padding: CryptoJS.pad.ZeroPadding
              });
              var data = decrypt.toString(CryptoJS.enc.Utf8);

              // 方式2 rsa 解密
              /* var privateKey = '私密';
               var decrypt = new JSEncrypt();
               decrypt.setPrivateKey(privateKey);
               var uncrypted = decrypt.decryptLong2(datas);
               var data = decodeURIComponent(uncrypted);*/
              return data;
          }

          options.dataFilter = ns;
          return ajax(options);
      }
  }
  • Vue
    安裝crypto-js與jsencrypt
npm install jsencrypt
npm install crypto-js
import Vue from 'vue'
import vueAxios from 'vue-axios'
import axios from 'axios'
import { getToken } from '@/utils/auth'
import { uuid } from '@/utils/utils'
import cryptoJs from 'crypto-js'
import JSEncrypt from 'jsencrypt'
import LE from '@/assets/config'
import store from '../store'
import router from '../router'
import { Toast } from 'vant'

Vue.use(vueAxios, axios)
Vue.use(Toast).use(cryptoJs)

// 創(chuàng)建axios實(shí)例
const service = axios.create({
baseURL: process.env.BASE_API, // api 的 base_url
timeout: 5000
})

const u32 = uuid(32)
const u16 = uuid(16)
const key = cryptoJs.enc.Latin1.parse(u32)
const iv = cryptoJs.enc.Latin1.parse(u16)

// request攔截器
service.interceptors.request.use(
(config) => {
  const con = config
  if (store.getters.token) {
    con.headers[LE.RequestTokenKey] = getToken()
  }
  // data數(shù)據(jù)加密
  if (typeof con.data === 'object') {
    con.data = JSON.stringify(con.data)
  }
  const encrypted = cryptoJs.AES.encrypt(con.data, key, {
    iv: iv,
    mode: cryptoJs.mode.CBC,
    padding: cryptoJs.pad.ZeroPadding
  })
  // ras 數(shù)據(jù)加密
  var publicKey = '123123'
  const jsencrypt = new JSEncrypt()
  jsencrypt.setPublicKey(publicKey)
  const ras = jsencrypt.encrypt(u32 + ';' + u16)

  if (con.method === 'post' || con.method === 'POST') {
    con.headers['Content-Type'] = 'application/json; charset=utf-8'
    con.data = ras + ';' + encrypted.toString()
  } else if (con.method === 'get' || con.method === 'GET') {
    con.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
    const params = ras + ';' + encrypted.toString()
    con.params = { params }
  }
  return con
},
(error) => {
  Promise.reject(error)
},
)

// response 攔截器
service.interceptors.response.use(
response => {
  let res = response.data
  // 數(shù)據(jù)解密
  // 方式1 aes 解密
  const decrypt = cryptoJs.AES.decrypt(res, key, {
    iv: iv,
    mode: cryptoJs.mode.CBC,
    padding: cryptoJs.pad.ZeroPadding
  })
  res = cryptoJs.enc.Utf8.stringify(decrypt).toString()
  res = JSON.parse(res)

  if (res.code === LE.response.NO_AUTH) {
    store.dispatch('FedLogOut')
      .then(() => {
        router.push({ path: '/login' })
      })
  } else if (res.code === LE.response.OK) {
    return res
  } else {
    const msg = '狀態(tài)碼:' + res.code + '異常提醒【' + res.msg + '】'
    Toast.fail({
      message: msg
    })
  }
}
,
error => {
  store.dispatch('FedLogOut')
    .then(() => {
      router.push({ path: '/login' })
    })
  Promise.reject(error)
},
)

export default service


加密方式

上訴把程序以及思路提供,可以根據(jù)自己需要的加密解密方式進(jìn)行處理宠哄,以下兩種方式我進(jìn)行了嘗試最終選擇了第二種壹将。

  • 方式一:RAS 加密
    • 什么是RAS,RSA加密算法是一種非對(duì)稱加密算法,由私鑰與公鑰組成一對(duì)密鑰,通過(guò)公鑰加密私鑰界面方式處理毛嫉。公鑰可以暴漏在客戶端诽俯,私鑰必須保密存儲(chǔ)在服務(wù)端。非對(duì)稱加密算法安全性更高承粤,但解密效率特別慢
    • 在請(qǐng)求時(shí)暴区,使用請(qǐng)求的公鑰對(duì)請(qǐng)求參數(shù)進(jìn)行加密,達(dá)到服務(wù)端過(guò)濾器時(shí)辛臊,使用私鑰進(jìn)行解密仙粱。完成請(qǐng)求參數(shù)的加密。
    • 在服務(wù)端響應(yīng)時(shí)彻舰,服務(wù)端采用響應(yīng)的公鑰加密伐割,客戶端私鑰進(jìn)行解密。完成結(jié)果的加密刃唤。
      上述中隔心,使用兩對(duì)密鑰處理。優(yōu)點(diǎn)安全性強(qiáng)尚胞。缺點(diǎn)1 響應(yīng)私鑰存儲(chǔ)在客戶端 2 當(dāng)出現(xiàn)大文本或者長(zhǎng)文本進(jìn)行加解密時(shí)效率非常慢硬霍,同時(shí)大部分工具類不支持長(zhǎng)文本的直接解密,需要使用分段加密-分段解密處理辐真,盡量不要這樣使用
  • 方式二:RAS + AES 加密
    • 什么是AES,AES算法稱為密碼學(xué)中的高級(jí)加密標(biāo)準(zhǔn),這個(gè)標(biāo)準(zhǔn)用來(lái)替代原先的DES崖堤。是一種對(duì)稱加密的算法侍咱。加解密效率較快,但安全性相對(duì)較弱密幔。
    • 請(qǐng)求時(shí)楔脯,客戶端生成AES的密鑰Key以及偏移量IV,對(duì)文本內(nèi)容進(jìn)行對(duì)稱加密,然后使用RAS對(duì)客戶端生成AES的密鑰Key以及偏移量IV進(jìn)行非對(duì)稱加密胯甩,進(jìn)行服務(wù)端傳遞昧廷。
    • 響應(yīng)時(shí)堪嫂,后臺(tái)使用傳遞的客戶端生成AES的密鑰Key以及偏移量IV進(jìn)行結(jié)果加密,客戶端是用同一個(gè)密鑰Key以及偏移量IV進(jìn)行解密木柬。
      RAS + AES 方式加密是指采用RAS算法對(duì)AES的加密的密鑰key(32位)以及偏移量iv(16位)進(jìn)行非對(duì)稱加密皆串,使用AES算法對(duì)需要傳遞的文本內(nèi)容進(jìn)行對(duì)稱加密。這種方式即可以保證安全性又能提高文本解析的效率眉枕。推薦使用恶复。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市速挑,隨后出現(xiàn)的幾起案子谤牡,更是在濱河造成了極大的恐慌,老刑警劉巖姥宝,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翅萤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡腊满,警方通過(guò)查閱死者的電腦和手機(jī)套么,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)糜烹,“玉大人违诗,你說(shuō)我怎么就攤上這事〈模” “怎么了诸迟?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)愕乎。 經(jīng)常有香客問(wèn)我阵苇,道長(zhǎng),這世上最難降的妖魔是什么感论? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任绅项,我火速辦了婚禮,結(jié)果婚禮上比肄,老公的妹妹穿的比我還像新娘快耿。我一直安慰自己,他們只是感情好芳绩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布掀亥。 她就那樣靜靜地躺著,像睡著了一般妥色。 火紅的嫁衣襯著肌膚如雪搪花。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音撮竿,去河邊找鬼吮便。 笑死,一個(gè)胖子當(dāng)著我的面吹牛幢踏,可吹牛的內(nèi)容都是我干的髓需。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼惑折,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼授账!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起惨驶,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤白热,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后粗卜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屋确,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年续扔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了攻臀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纱昧,死狀恐怖刨啸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情识脆,我是刑警寧澤设联,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站灼捂,受9級(jí)特大地震影響离例,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜悉稠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一宫蛆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧的猛,春花似錦耀盗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至猫牡,卻和暖如春胡诗,著一層夾襖步出監(jiān)牢的瞬間邓线,已是汗流浹背淌友。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工煌恢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人震庭。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓瑰抵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親器联。 傳聞我的和親對(duì)象是個(gè)殘疾皇子二汛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 原文鏈接:https://docs.spring.io/spring-boot/docs/1.4.x/refere...
    pseudo_niaonao閱讀 4,692評(píng)論 0 9
  • 要加“m”說(shuō)明是MB,否則就是KB了. -Xms:初始值 -Xmx:最大值 -Xmn:最小值 java -Xms8...
    dadong0505閱讀 4,829評(píng)論 0 53
  • 這篇文章介紹了Mobile BI(移動(dòng)商務(wù)智能)使用過(guò)程中涉及的各種身份認(rèn)證的方式拨拓,主要目的是對(duì)這些方式的原理進(jìn)行...
    雨_樹閱讀 2,014評(píng)論 1 2
  • 最近公司用到RSA數(shù)據(jù)加密傳輸肴颊,本人也只會(huì)使用,并不知其原理渣磷,剛好今天在csdn看到一位大牛的博客寫得很到位婿着,遂搬...
    爸比好酷閱讀 1,418評(píng)論 0 1
  • “頭馬是一個(gè)非盈利組織” 社會(huì)環(huán)境復(fù)雜,我們要保護(hù)好自己醋界,保護(hù)好俱樂(lè)部竟宋。 不要用頭馬的名義去推廣任何的公益活動(dòng)。 ...
    閃電丸閱讀 388評(píng)論 0 1