客戶端JavaScript加密數據,服務端Java解密數據


原文:http://blog.csdn.net/peterwanghao/article/details/43303807

在普通的頁面提交時,如果沒有使用SSL,提交的數據將使用純文本的方式發送。如果使用抓包工具可以輕易地截獲一些關鍵數據。

jCryption是一個jQuery插件,能夠加密由Forms提交的POST/GET數據。官網地址:http://www.jcryption.org/

 

未加密處理的效果如下:可很容易地看到登錄時的用戶名和口令。

 

使用jCryption后效果如下,提交的數據為密文。

 

本例中服務端使用Java進行解密,使用了一個開源項目JavaCription,官網地址:https://jcryptionforjava.wordpress.com/。實現了針對jCryption2.0的Java解密。

處理機制如下:

1、客戶端從服務端請求一個RSA公鑰

2、客戶端產生一個隨機數作為AES密鑰,用RSA公鑰進行加密,發送到服務端

3、服務端用RSA私鑰進行解密,同時將AES密鑰保持到會話中

4、服務端用AES算法加密AES密鑰並送回給客戶端

5、客戶端用AES算法解密,並與本地保存的AES密鑰做比對,如果相符就認為服務端是合法的

6、客戶端提交數據,數據用AES密鑰進行加密

在此版本里為提供效率,只使用RSA非對稱算法進行密鑰交換,數據的加解密使用AES對稱算法。

 

客戶端

引入兩個js文件

<script type="text/JavaScript" src="js/jquery-2.1.3.min.js"></script>
<script type="text/javascript" src="js/jquery.jcryption.js"></script>

表單加密,設定兩個地址:1)獲取公鑰 2)握手交換AES密鑰

<script type="text/javascript">
$(function() {
$("#form1").jCryption();
});
$.jCryption.defaultOptions.getKeysURL="encrypt?generateKeyPair=true";
$.jCryption.defaultOptions.handshakeURL="encrypt?handshake=true";
</script>

 

服務端

密鑰服務Servlet

public class CryptoServlet extends HttpServlet{
    /**
     * serialVersionUID
     */
    private static final long serialVersionUID = 4510110365995157499L;

    /**
     * Handles a POST request
     * 
     * @see HttpServlet
     */
    public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        /** Generates a KeyPair for RSA **/
        if (req.getParameter("generateKeyPair") != null && req.getParameter("generateKeyPair").equals("true")) {

            JCryption jc = new JCryption();
            KeyPair keys = jc.getKeyPair();
            request.getSession().getServletContext().setAttribute("jCryptionKeys", keys);
            String e = jc.getPublicExponent();
            String n = jc.getKeyModulus();
            String md = String.valueOf(jc.getMaxDigits());

            /** Sends response **/
            PrintWriter out = response.getWriter();
            out.print("{\"e\":\"" + e + "\",\"n\":\"" + n + "\",\"maxdigits\":\"" + md + "\"}");
            return;
        }
        /** jCryption handshake **/
        else if (req.getParameter("handshake") != null && req.getParameter("handshake").equals("true")) {

            /** Decrypts password using private key **/
            JCryption jc = new JCryption((KeyPair) request.getSession().getServletContext()
                    .getAttribute("jCryptionKeys"));
            String a = req.getParameter("key");
            System.out.println(a);
            String key = jc.decrypt(req.getParameter("key"));

            request.getSession().getServletContext().removeAttribute("jCryptionKeys");
            request.getSession().getServletContext().setAttribute("jCryptionKey", key);

            /** Encrypts password using AES **/
            String ct = AesCtr.encrypt(key, key, 256);

            /** Sends response **/
            PrintWriter out = response.getWriter();
            out.print("{\"challenge\":\"" + ct + "\"}");

            return;
        }
        /** jCryption request to decrypt a String **/
        else if (req.getParameter("decryptData") != null && req.getParameter("decryptData").equals("true")
                && req.getParameter("jCryption") != null) {

            /** Decrypts the request using password **/
            String key = (String) request.getSession().getServletContext().getAttribute("jCryptionKey");

            String pt = AesCtr.decrypt(req.getParameter("jCryption"), key, 256);

            /** Sends response **/
            PrintWriter out = response.getWriter();
            out.print("{\"data\":\"" + pt + "\"}");
            return;
        }
        /** jCryption request to encrypt a String **/
        else if (req.getParameter("encryptData") != null && req.getParameter("encryptData").equals("true")
                && req.getParameter("jCryption") != null) {

            /** Encrypts the request using password **/
            String key = (String) request.getSession().getServletContext().getAttribute("jCryptionKey");

            String ct = AesCtr.encrypt(req.getParameter("jCryption"), key, 256);

            /** Sends response **/
            PrintWriter out = response.getWriter();
            out.print("{\"data\":\"" + ct + "\"}");
            return;
        }
        /** A test request from jCryption **/
        else if (req.getParameter("decryptTest") != null && req.getParameter("decryptTest").equals("true")) {

            /** Encrypts a timestamp **/
            String key = (String) request.getSession().getServletContext().getAttribute("jCryptionKey");

            String date = DateFormat.getInstance().format(new Date());

            String ct = AesCtr.encrypt(date, key, 256);

            /** Sends response **/
            PrintWriter out = response.getWriter();
            out.print("{\"encrypted\":\"" + ct + "\", \"unencrypted\":\"" + date + "\"}");
            return;
        }
    }

    /**
     * Handles a GET request
     * 
     * @see HttpServlet
     */
    public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
        doPost(req, res);
    }
}

 

過慮器,進行數據解密

 

密文:5QN8EsTjylTGSyvrmYGXDUD/MjF3qcl58pZtI7xhCk5HMUYFjf7kJe/leQLAuqzW4dPUNw==
明文:loginName=admin&password=admin&Submit=提交

public class SecureFilter implements Filter{
    private FilterConfig conf;
    
    public void destroy() {
        // TODO Auto-generated method stub
        
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        String jCryption = request.getParameter("jCryption");
        System.out.println(jCryption);
        String key = (String) conf.getServletContext().getAttribute("jCryptionKey");

        String source = AesCtr.decrypt(jCryption, key, 256);
        System.out.println(source);
        
        String[] params = source.split("&");
        for(int i=0;i<params.length;i++){
            String [] aparam = params[i].split("=");
            request.setAttribute(aparam[0], aparam[1]);
        }
        
        chain.doFilter(request, response);
        
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        this.conf = filterConfig;
        
    }

}

 

處理器,從request.getAttribute中獲取數據

String loginName = passwordAuthcInfo.getLoginName();
        String loginPassword = passwordAuthcInfo.getPassword();
        if(loginName == null && loginPassword == null){
            loginName = (String)request.getAttribute("loginName");
            loginPassword = (String)request.getAttribute("password");
        }

 


免責聲明!

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



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