Javascript端加密java服务端解密


通常我们会通过htts来保证传输安全,但如果我们不用https,如何通过javascript来保证浏览器端发送的参数进行加密,并且通过RSA算法来处理。


这里我们可以利用jquery的一个加密插件jcryption来处理,可以参考

http://jcryption.org/#examples

现在版本是3.0 但是没有java端的实现,下次有时间再研究。现在这个用的是1.1的版本

这个可以在

http://linkwithweb.googlecode.com/svn/trunk/Utilities/jCryptionTutorial获取


不过他的服务端有个缺陷我修改了。

接来大致介绍如下:


1.首先服务端有产生publicKeyservlet

package com.gsh.oauth.auth.servlet;


import java.io.IOException;

import java.security.KeyPair;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;


import com.gsh.oauth.auth.util.JCryptionUtil;


/**

*Servlet implementation class EncryptionServlet

*/

public class EncryptionServlet extendsHttpServlet {

      privatestatic final long serialVersionUID = 1L;


      /**

       * Default constructor.

       */

      publicEncryptionServlet() {

              //TODO Auto-generated constructor stub

      }


      /**

       * @see HttpServlet#service(HttpServletRequestrequest, HttpServletResponse response)

       */

      protectedvoid service(HttpServletRequest request,

                     HttpServletResponseresponse) throws ServletException, IOException {

              intKEY_SIZE = 1024;

              if(request.getParameter("generateKeypair") != null) {


                     JCryptionUtiljCryptionUtil = new JCryptionUtil();


                     KeyPairkeys = null;

                     //if(request.getSession().getAttribute("keys") == null) { //这里注释掉否则第二次请求会500

                            keys= jCryptionUtil.generateKeypair(KEY_SIZE);

                            request.getSession().setAttribute("keys",keys);

                     //}


                     StringBufferoutput = new StringBuffer();


                     Stringe = JCryptionUtil.getPublicKeyExponent(keys);

                     Stringn = JCryptionUtil.getPublicKeyModulus(keys);

                     Stringmd = String.valueOf(JCryptionUtil.getMaxDigits(KEY_SIZE));


                     output.append("{\"e\":\"");

                     output.append(e);

                     output.append("\",\"n\":\"");

                     output.append(n);

                     output.append("\",\"maxdigits\":\"");

                     output.append(md);

                     output.append("\"}");


                     output.toString();

                     response.getOutputStream().print(

                                   output.toString().replaceAll("\r","").replaceAll("\n", "")

                                                  .trim());

              }else {

                     response.getOutputStream().print(String.valueOf(false));

              }

      }


}


2.Client例子

<html>

<head>

<title>Login formtitle>

head>

<metahttp-equiv="Content-Type"

content="text/html; charset=utf-8">


<scriptsrc="../js/jquery-1.4.2.min.js"type="text/javascript">script>

<scriptsrc="../js/jquery-ui-1.8.2.custom.min.js"

type="text/javascript">script>

<scripttype="text/javascript"

src="../js/security/jquery.jcryption-1.1.min.js">script>


<scripttype="text/javascript">

  $(document).ready(function() {

var $statusText = $('').hide();

       $("#status_container").append($statusText);

       $("#lf").jCryption({

           getKeysURL:"/gsh/oauth/encryption?generateKeypair=true",

                                       beforeEncryption: function(){

                                           $statusText

                                                  .text("Test Code")

                                                  .show();

returntrue;

                                       },

                                       encryptionFinished: function(

                                              encryptedString,

                                              objectLength){

                                           $statusText

                                                  .text(encryptedString);

returntrue;

                                       }

                                   });

                 });

script>

<body>


<formid="lf"action="/gsh/oauth/authorization"

method="post">

<fieldset><legend>loginlegend>

<div>

<div>client_id:<br>

<inputtype="text"size="45"name="client_id"value="">div>

<div>redirect_uri:<br>

<inputtype="text"size="45"name="redirect_uri"value="">div>

div>

<div>loginid:<br>

<inputtype="text"size="45"name="loginid"value="">div>

div>

<div>password:<br>

<inputtype="password"size="45"name="password"value="">div>

div>

<div>

<p><inputtype="submit"/><spanid="status_container">span>p>

div>

fieldset>

form>

body>

html>


上面看代码可以看出他通过/gsh/oauth/encryption?generateKeypair=true来先请求获取public 然后通过jcryption进行加密然后post到服务端。Encryption就是上面的EncryptionServlet

通过浏览器工具可以看到表单里面的数据加密为


jCryption=95f1589502288050e08b4bd8b1a360341cf616d9054531b85a6ef85783c1723b46686ec454ee81f1304fa2370ce24c4d9c06f84d47aa4bdf99310ae12b514db19bfcc325f3a39a584c23b1546550f4e0635c12486f2fd84dec137e1c61cfa775dfa3057a1f0154712aaba0af0cc61810282780f15bed909c24a184e66ab39f2e

3.目标servletauthorization)的解密


publicclassAuthorization extends HttpServlet {


protectedvoiddoGet(HttpServletRequest httpServletRequest,

          HttpServletResponsehttpServletResponse) throws ServletException,

          IOException{


PrintWriter out = httpServletResponse.getWriter();


      KeyPair keys = (KeyPair)httpServletRequest.getSession().getAttribute("keys");

      String encrypted =httpServletRequest.getParameter("epCryption");


      String client_id = null;

   Stringredirect_uri = null;

   Stringloginid = null;

   Stringpassword = null;


try {

              Stringdata = JCryptionUtil.decrypt(encrypted, keys);

              httpServletRequest.getSession().removeAttribute("keys");

Mapparams = JCryptionUtil.parse(data, "UTF-8");

              client_id= (String) params.get("client_id");

              redirect_uri= (String) params.get("redirect_uri");

              loginid= (String) params.get("loginid");

password = (String)params.get("password");


          }catch(Throwable e) {

              e.printStackTrace();

          }

}


   }


上面至少片段,需要相关的jsjava问题,请在svn上面获取。另外还需要bcprov-jdk15-1.46.jar

可以在http://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15/1.46

获取。