国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

web開發安全之請求及返回流數據加解密實踐

Taonce / 2781人閱讀

摘要:以上為加解密在實際開發過程中代碼,代碼提交是對于和等符號進行過濾,防止注入,在開發過程中可以參考此代碼進行適當修改進行使用

web開發過程中對post請求過來的整個請求流數據,怎樣保證post在傳輸過程中被截取后無法獲取到用戶提交請求實際數據,保證請求安全,在實踐過程中我們采用過濾器(Filter)來實現流截取完成這個代碼post請求流數據及返回數據加解密

一、請求數據流解密

1 請求數據提交filter進行數據過濾,過濾器類主要用于創建HttpServletRequest,實現解密,將解密后的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、提交數據解密:前端或者app端對提交數據流數據解密,繼承HttpServletRequestWrapper方法實現自己的HttpServletRequest,拷貝原始數據流,getParameterValues寫入解密方法,Spring框架進行自動解包是會通過getParameterValues讀取數據流,進行自動解包,將數據set到對象,完成數據解密過程(copy數據流主要解決流只能讀取一次問題)

    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;
        // 緩存請求body 讀取Post數據
        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解密數據
            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解密數據
            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解密數據
            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解密數據
                if (StringUtils.isNoneBlank(value)) {
                    value = value.replaceAll("<", "<");
                    value = value.replaceAll(">", ">");
                }
                return value;
            } else {
                return null;
            }
        } else {
            return v.toString();
        }
    }

}
二、返回數據流加密

1、繼承過濾器接口實現返回數據過濾攔截,將返回數據轉換為代理類,通過代理類改變處理返回數據流進行加密并將加密后數據重新寫入到流中返回(使用代理類主要是為了解決流只能讀取一次問題)

    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);// 轉換成代理類
            // 這里只攔截返回,直接讓請求過去,如果在請求前有處理,可以在這里處理
            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);
                    // ......根據需要處理返回值
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //將加密后數據重新寫如后刷新數據流
                ServletOutputStream out = response.getOutputStream();
                out.write(ciphertext.getBytes());
                out.flush();
            }
    }
}

2.返回值輸出代理,通過代理獲取返回值信息內容

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請求加密過程會進行URL編碼傳入,需要進行URLDecoder.decode進行解碼后才能進行解密操作

     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;
            }
}

實際AES加解密代碼塊,本文檔采用aes進行加密,也可以自行可以換其它加密方式進行加密

    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模式,需要一個向量iv,可增加加密算法的強度
            IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
            //此處使用BASE64做轉碼。
            return new BASE64Encoder().encode(encrypted);
        } catch (Exception ex) {
            return null;
        }
    }

}

以上為加解密在實際開發過程中代碼,代碼提交是對于>和<等符號進行過濾,防止sql注入,在開發過程中可以參考此代碼進行適當修改進行使用

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/71066.html

相關文章

  • web開發安全請求返回數據解密實踐

    摘要:以上為加解密在實際開發過程中代碼,代碼提交是對于和等符號進行過濾,防止注入,在開發過程中可以參考此代碼進行適當修改進行使用 web開發過程中對post請求過來的整個請求流數據,怎樣保證post在傳輸過程中被截取后無法獲取到用戶提交請求實際數據,保證請求安全,在實踐過程中我們采用過濾器(Filter)來實現流截取完成這個代碼post請求流數據及返回數據加解密 一、請求數據流解密 1 請求...

    Shonim 評論0 收藏0
  • 墻裂推薦:搜云庫技術團隊,面試必備的技術干貨

    摘要:今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 面試必備 面試必備:深入Spring MVC DispatchServlet 源碼...

    SegmentFault 評論0 收藏0
  • 墻裂推薦:搜云庫技術團隊,面試必備的技術干貨

    摘要:今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 今天整理了一下近大半年以來的一些文章,和我的預期一樣,很多文章我都忘記自己曾經寫過了,這個記錄的過程讓我也有了新的理解。希望大家,收藏,點贊,加轉發。 面試必備 面試必備:深入Spring MVC DispatchServlet 源碼...

    Neilyo 評論0 收藏0
  • 微服務分布式文件系統

    摘要:于是便誕生了隨行付分布式文件系統簡稱,提供的海量安全低成本高可靠的云存儲服務。子系統相關流程圖如下核心實現主要為隨行付各個業務系統提供文件共享和訪問服務,并且可以按應用統計流量命中率空間等指標。 背景 傳統Web應用中所有的功能部署在一起,圖片、文件也在一臺服務器;應用微服務架構后,服務之間的圖片共享通過FTP+Nginx靜態資源的方式進行訪問,文件共享通過nfs磁盤掛載的方式進行訪問...

    stormjun 評論0 收藏0
  • 鵝廠干貨 | 騰訊游戲APP協議迭代的那些事

    摘要:本文則主要總結了心悅俱樂部的接入層從文本協議到二進制協議迭代過程中的技術方案,包括協議規范安全性等方面的內容。在心悅的文本協議方案中,采用的是對請求數據進行模式的加密。包括明文的協議包頭和密文的二進制流。 歡迎大家前往騰訊云+社區,獲取更多騰訊海量技術實踐干貨哦~。 作者:羅廣鎮 | 騰訊移動開發工程師 App與后臺通信通常有采用json等文本協議或者采用二進制協議,本文則主要總結了心...

    luck 評論0 收藏0

發表評論

0條評論

Taonce

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<