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.     首先服务端有产生publicKey的servlet:
  package com.gsh.oauth.auth.servlet;
   
  import java.io.IOException;
  import java.security.KeyPair;
   
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
   
  import com.gsh.oauth.auth.util.JCryptionUtil;
   
  /**
   * Servlet implementation class EncryptionServlet
   */
  public class EncryptionServlet extends HttpServlet {
         private static final long serialVersionUID = 1L;
   
         /**
          * Default constructor.
          */
         public EncryptionServlet() {
                 // TODO Auto-generated constructor stub
         }
   
         /**
          * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
          */
         protected void service(HttpServletRequest request,
                        HttpServletResponse response) throws ServletException, IOException {
                 int KEY_SIZE = 1024;
                 if (request.getParameter("generateKeypair") != null) {
   
                        JCryptionUtil jCryptionUtil = new JCryptionUtil();
   
                        KeyPair keys = null;
                        //if (request.getSession().getAttribute("keys") == null) { //这里注释掉 否则第二次请求会500
                               keys = jCryptionUtil.generateKeypair(KEY_SIZE);
                               request.getSession().setAttribute("keys", keys);
                        //}
   
                        StringBuffer output = new StringBuffer();
   
                        String e = JCryptionUtil.getPublicKeyExponent(keys);
                        String n = JCryptionUtil.getPublicKeyModulus(keys);
                        String md = String.valueOf(JCryptionUtil.getMaxDigits(KEY_SIZE));
   
                        output.append("{\"e\":\"");
                        output.append(e);/Files/linugb118/bcprov-jdk15-1.46.jar.zip
                        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 form</title>
  </head>
  <meta http-equiv="Content-Type"
      content="text/html; charset=utf-8">
   
  <script src="../js/jquery-1.4.2.min.js" type="text/javascript"></script>
  <script src="../js/jquery-ui-1.8.2.custom.min.js"
      type="text/javascript"></script>
  <script type="text/javascript"
      src="../js/security/jquery.jcryption-1.1.min.js"></script>    
      
  <script type="text/javascript">
      $(document).ready(function() {
          var $statusText = $('<span id="status"></span>').hide();
          $("#status_container").append($statusText);
          $("#lf").jCryption({ 
              getKeysURL:"/gsh/oauth/encryption?generateKeypair=true",
                                          beforeEncryption : function() {
                                              $statusText
                                                     .text("Test Code")
                                                     .show();
                                              return true;
                                          },
                                          encryptionFinished : function(
                                                 encryptedString,
                                                 objectLength) {
                                              $statusText
                                                     .text(encryptedString);
                                              return true;
                                          }
                                      });
                    });
  </script>
  <body>
   
  <form id="lf" action="/gsh/oauth/authorization"
      method="post">
  <fieldset><legend>login</legend>
  <div>
  <div>client_id:<br>
  <input type="text" size="45" name="client_id" value=""></div>
  <div>redirect_uri:<br>
  <input type="text" size="45" name="redirect_uri" value=""></div>
  </div>
  <div>loginid:<br>
  <input type="text" size="45" name="loginid" value=""></div>
  </div>
  <div>password:<br>
  <input type="password" size="45" name="password" value=""></div>
  </div>
  <div>
  <p><input type="submit" /><span id="status_container"></span></p>
  </div>
  </fieldset>
  </form>
  </body>
  </html>
   
  上面看代码可以看出 他通过/gsh/oauth/encryption?generateKeypair=true来先请求获取public 然后通过jcryption进行加密 然后post到服务端。Encryption就是上面的EncryptionServlet。
  通过浏览器工具可以看到表单里面的数据加密为
   
  jCryption=95f1589502288050e08b4bd8b1a360341cf616d9054531b85a6ef85783c1723b46686ec454ee81f1304fa2370ce24c4d9c06f84d47aa4bdf99310ae12b514db19bfcc325f3a39a584c23b1546550f4e0635c12486f2fd84dec137e1c61cfa775dfa3057a1f0154712aaba0af0cc61810282780f15bed909c24a184e66ab39f2e
  3. 目标servlet(authorization)的解密 
   
  public class Authorization extends HttpServlet {
   
      protected void doGet(HttpServletRequest httpServletRequest,
             HttpServletResponse httpServletResponse) throws ServletException,
             IOException {
         
  PrintWriter out = httpServletResponse.getWriter();
          
          KeyPair keys = (KeyPair) httpServletRequest.getSession().getAttribute("keys");
          String encrypted = httpServletRequest.getParameter("epCryption");
          
          String client_id = null;
      String redirect_uri = null;
      String loginid = null;
      String password = null;
   
         try {
                 String data = JCryptionUtil.decrypt(encrypted, keys);
                 httpServletRequest.getSession().removeAttribute("keys");
                 Map params = 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();
             }
  }
   
      }
   
  上面至少片段,需要相关的js和java问题,请在svn上面获取。另外还需要bcprov-jdk15-1.46.jar
  可以在http://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15/1.46
  获取。