摘要:以上為加解密在實(shí)際開發(fā)過程中代碼,代碼提交是對(duì)于和等符號(hào)進(jìn)行過濾,防止注入,在開發(fā)過程中可以參考此代碼進(jìn)行適當(dāng)修改進(jìn)行使用
web開發(fā)過程中對(duì)post請(qǐng)求過來的整個(gè)請(qǐng)求流數(shù)據(jù),怎樣保證post在傳輸過程中被截取后無法獲取到用戶提交請(qǐng)求實(shí)際數(shù)據(jù),保證請(qǐng)求安全,在實(shí)踐過程中我們采用過濾器(Filter)來實(shí)現(xiàn)流截取完成這個(gè)代碼post請(qǐng)求流數(shù)據(jù)及返回?cái)?shù)據(jù)加解密
一、請(qǐng)求數(shù)據(jù)流解密1 請(qǐng)求數(shù)據(jù)提交filter進(jìn)行數(shù)據(jù)過濾,過濾器類主要用于創(chuàng)建HttpServletRequest,實(shí)現(xiàn)解密,將解密后的request返回到下層
public class CharacterFilter implements Filter{ @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; TsRequest wrapRequest= new TsRequest(request,request.getParameterMap()); chain.doFilter(wrapRequest, res); } }
2、提交數(shù)據(jù)解密:前端或者app端對(duì)提交數(shù)據(jù)流數(shù)據(jù)解密,繼承HttpServletRequestWrapper方法實(shí)現(xiàn)自己的HttpServletRequest,拷貝原始數(shù)據(jù)流,getParameterValues寫入解密方法,Spring框架進(jìn)行自動(dòng)解包是會(huì)通過getParameterValues讀取數(shù)據(jù)流,進(jìn)行自動(dòng)解包,將數(shù)據(jù)set到對(duì)象,完成數(shù)據(jù)解密過程(copy數(shù)據(jù)流主要解決流只能讀取一次問題)
public class TsRequest extends HttpServletRequestWrapper{ private Map params; public static final int BUFFER_SIZE = 4096; private byte[] requestBody = null; public TsRequest(HttpServletRequest request, Map newParams) { super(request); this.params = newParams; // 緩存請(qǐng)求body 讀取Post數(shù)據(jù) String method = request.getMethod(); if (("POST").equals(request.getMethod())) { try { ByteArrayOutputStream out = copy(request.getInputStream()); requestBody = out.toByteArray(); } catch (IOException e) { e.printStackTrace(); } } } public static ByteArrayOutputStream copy(InputStream in) throws IOException { String data = convertStreamToString(in); if (data != null && data.indexOf("time") == -1) { try { data = AESDataUtils.decrypt(data); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } byte bytes[] = data.getBytes("UTF-8"); ByteArrayOutputStream out = new ByteArrayOutputStream(bytes.length); out.write(bytes, 0, bytes.length); out.flush(); return out; } public static String convertStreamToString(InputStream is) throws UnsupportedEncodingException { BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); StringBuilder sb = new StringBuilder(); String line = null; try { while ((line = reader.readLine()) != null) { sb.append(line); } } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } return sb.toString(); } /** * 重寫 getInputStream() */ @Override public ServletInputStream getInputStream() throws IOException { if (requestBody == null) { requestBody = new byte[0]; } final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } }; } /** * 重寫 getReader() */ @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } public Map getParameterMap() { return params; } public Enumeration getParameterNames() { Vector l = new Vector(params.keySet()); return l.elements(); } public String[] getParameterValues(String name) { Object v = params.get(name); if (v == null) { return null; } else if (v instanceof String[]) { String[] value = (String[]) v; for (int i = 0; i < value.length; i++) { // AES解密數(shù)據(jù) value[i]=AESDataUtils.decrypt(value[i]); if (StringUtils.isNoneEmpty(value[i])) { value[i] = value[i].replaceAll("<", "<"); value[i] = value[i].replaceAll(">", ">"); } } return (String[]) value; } else if (v instanceof String) { String value = (String) v; value=AESDataUtils.decrypt(value); // AES解密數(shù)據(jù) if (StringUtils.isNoneBlank(value)) { value = value.replaceAll("<", "<"); value = value.replaceAll(">", ">"); } return new String[] { (String) value }; } else { return new String[] { v.toString() }; } } public String getParameter(String name) { Object v = params.get(name); if (v == null) { return null; } else if (v instanceof String) { String value = (String) v; value = AESDataUtils.decrypt(value); // AES解密數(shù)據(jù) if (StringUtils.isNoneBlank(value)) { value = value.replaceAll("<", "<"); value = value.replaceAll(">", ">"); } return (String) value; } else if (v instanceof String[]) { String[] strArr = (String[]) v; if (strArr.length > 0) { String value = strArr[0]; String aesdata=AESDataUtils.decrypt(value); if(StringUtils.isNoneEmpty(aesdata)){ value =aesdata ; } // AES解密數(shù)據(jù) if (StringUtils.isNoneBlank(value)) { value = value.replaceAll("<", "<"); value = value.replaceAll(">", ">"); } return value; } else { return null; } } else { return v.toString(); } } }二、返回?cái)?shù)據(jù)流加密
1、繼承過濾器接口實(shí)現(xiàn)返回?cái)?shù)據(jù)過濾攔截,將返回?cái)?shù)據(jù)轉(zhuǎn)換為代理類,通過代理類改變處理返回?cái)?shù)據(jù)流進(jìn)行加密并將加密后數(shù)據(jù)重新寫入到流中返回(使用代理類主要是為了解決流只能讀取一次問題)
public class ResponseFilter implements Filter{ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { filterChain.doFilter(request, response); ResponseWrapper wrapperResponse = new ResponseWrapper( (HttpServletResponse) response);// 轉(zhuǎn)換成代理類 // 這里只攔截返回,直接讓請(qǐng)求過去,如果在請(qǐng)求前有處理,可以在這里處理 filterChain.doFilter(request, wrapperResponse); byte[] content = wrapperResponse.getContent();// 獲取返回值 if (content.length > 0) { String str = new String(content, "UTF-8"); String ciphertext = null; try { ciphertext = AESDataUtils.encrypt(str); // ......根據(jù)需要處理返回值 } catch (Exception e) { e.printStackTrace(); } //將加密后數(shù)據(jù)重新寫如后刷新數(shù)據(jù)流 ServletOutputStream out = response.getOutputStream(); out.write(ciphertext.getBytes()); out.flush(); } } }
2.返回值輸出代理,通過代理獲取返回值信息內(nèi)容
public class ResponseWrapper extends HttpServletResponseWrapper { private ByteArrayOutputStream buffer; private ServletOutputStream out; public ResponseWrapper(HttpServletResponse httpServletResponse) { super(httpServletResponse); buffer = new ByteArrayOutputStream(); out = new WrapperOutputStream(buffer); } @Override public ServletOutputStream getOutputStream() throws IOException { return out; } @Override public void flushBuffer() throws IOException { if (out != null) { out.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); } } }三、使用工具類代碼
AES加密工具類加解密代碼模塊,主要http請(qǐng)求加密過程會(huì)進(jìn)行URL編碼傳入,需要進(jìn)行URLDecoder.decode進(jìn)行解碼后才能進(jìn)行解密操作
public class AESDataUtils { /** * 解密 * @param value * @return */ public static String decrypt(String value){ if(StringUtils.isNoneEmpty(value)){ if(value.indexOf("%")>-1){ value=URLDecoder.decode(value); } } try { return AESUtils.decrypt(value); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * 加密 * @param value * @return */ public static String encrypt(String value){ value=AESUtils.encrypt(value); value=URLEncoder.encode(value); return value; } }
實(shí)際AES加解密代碼塊,本文檔采用aes進(jìn)行加密,也可以自行可以換其它加密方式進(jìn)行加密
public class AESUtils { private static String secretKey = "秘鑰"; private static String ivParameter = ""; /** * aes 解密 * * @param sSrc * @return * @throws Exception */ public static String decrypt(String sSrc) throws Exception { try { byte[] raw = secretKey.getBytes("ASCII"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES / CBC / PKCS5Padding"); IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密 byte[] original = cipher.doFinal(encrypted1); String originalString = new String(original, "UTF-8"); return originalString; } catch (Exception ex) { return null; } } //加密 public static String encrypt(String sSrc) { try { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] raw = secretKey.getBytes(); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); //使用CBC模式,需要一個(gè)向量iv,可增加加密算法的強(qiáng)度 IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8")); //此處使用BASE64做轉(zhuǎn)碼。 return new BASE64Encoder().encode(encrypted); } catch (Exception ex) { return null; } } }
以上為加解密在實(shí)際開發(fā)過程中代碼,代碼提交是對(duì)于>和<等符號(hào)進(jìn)行過濾,防止sql注入,在開發(fā)過程中可以參考此代碼進(jìn)行適當(dāng)修改進(jìn)行使用
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/11339.html
摘要:以上為加解密在實(shí)際開發(fā)過程中代碼,代碼提交是對(duì)于和等符號(hào)進(jìn)行過濾,防止注入,在開發(fā)過程中可以參考此代碼進(jìn)行適當(dāng)修改進(jìn)行使用 web開發(fā)過程中對(duì)post請(qǐng)求過來的整個(gè)請(qǐng)求流數(shù)據(jù),怎樣保證post在傳輸過程中被截取后無法獲取到用戶提交請(qǐng)求實(shí)際數(shù)據(jù),保證請(qǐng)求安全,在實(shí)踐過程中我們采用過濾器(Filter)來實(shí)現(xiàn)流截取完成這個(gè)代碼post請(qǐng)求流數(shù)據(jù)及返回?cái)?shù)據(jù)加解密 一、請(qǐng)求數(shù)據(jù)流解密 1 請(qǐng)求...
摘要:今天整理了一下近大半年以來的一些文章,和我的預(yù)期一樣,很多文章我都忘記自己曾經(jīng)寫過了,這個(gè)記錄的過程讓我也有了新的理解。希望大家,收藏,點(diǎn)贊,加轉(zhuǎn)發(fā)。 今天整理了一下近大半年以來的一些文章,和我的預(yù)期一樣,很多文章我都忘記自己曾經(jīng)寫過了,這個(gè)記錄的過程讓我也有了新的理解。希望大家,收藏,點(diǎn)贊,加轉(zhuǎn)發(fā)。 面試必備 面試必備:深入Spring MVC DispatchServlet 源碼...
摘要:今天整理了一下近大半年以來的一些文章,和我的預(yù)期一樣,很多文章我都忘記自己曾經(jīng)寫過了,這個(gè)記錄的過程讓我也有了新的理解。希望大家,收藏,點(diǎn)贊,加轉(zhuǎn)發(fā)。 今天整理了一下近大半年以來的一些文章,和我的預(yù)期一樣,很多文章我都忘記自己曾經(jīng)寫過了,這個(gè)記錄的過程讓我也有了新的理解。希望大家,收藏,點(diǎn)贊,加轉(zhuǎn)發(fā)。 面試必備 面試必備:深入Spring MVC DispatchServlet 源碼...
摘要:于是便誕生了隨行付分布式文件系統(tǒng)簡稱,提供的海量安全低成本高可靠的云存儲(chǔ)服務(wù)。子系統(tǒng)相關(guān)流程圖如下核心實(shí)現(xiàn)主要為隨行付各個(gè)業(yè)務(wù)系統(tǒng)提供文件共享和訪問服務(wù),并且可以按應(yīng)用統(tǒng)計(jì)流量命中率空間等指標(biāo)。 背景 傳統(tǒng)Web應(yīng)用中所有的功能部署在一起,圖片、文件也在一臺(tái)服務(wù)器;應(yīng)用微服務(wù)架構(gòu)后,服務(wù)之間的圖片共享通過FTP+Nginx靜態(tài)資源的方式進(jìn)行訪問,文件共享通過nfs磁盤掛載的方式進(jìn)行訪問...
摘要:本文則主要總結(jié)了心悅俱樂部的接入層從文本協(xié)議到二進(jìn)制協(xié)議迭代過程中的技術(shù)方案,包括協(xié)議規(guī)范安全性等方面的內(nèi)容。在心悅的文本協(xié)議方案中,采用的是對(duì)請(qǐng)求數(shù)據(jù)進(jìn)行模式的加密。包括明文的協(xié)議包頭和密文的二進(jìn)制流。 歡迎大家前往騰訊云+社區(qū),獲取更多騰訊海量技術(shù)實(shí)踐干貨哦~。 作者:羅廣鎮(zhèn) | 騰訊移動(dòng)開發(fā)工程師 App與后臺(tái)通信通常有采用json等文本協(xié)議或者采用二進(jìn)制協(xié)議,本文則主要總結(jié)了心...
閱讀 987·2021-11-24 10:30
閱讀 2316·2021-10-08 10:04
閱讀 3949·2021-09-30 09:47
閱讀 1433·2021-09-29 09:45
閱讀 1435·2021-09-24 10:33
閱讀 6234·2021-09-22 15:57
閱讀 2351·2021-09-22 15:50
閱讀 4079·2021-08-30 09:45