原文: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");
}

客户端JavaScript加密数据,服务端Java解密数据的更多相关文章

  1. 基于NIO的同步非阻塞编程完整案例,客户端发送请求,服务端获取数据并返回给客户端数据,客户端获取返回数据

    这块还是挺复杂的,挺难理解,但是多练几遍,多看看研究研究其实也就那样,就是一个Selector轮询的过程,这里想要双向通信,客户端和服务端都需要一个Selector,并一直轮询, 直接贴代码: Ser ...

  2. java版gRPC实战之六:客户端动态获取服务端地址

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  3. IOS开发系列之阿堂教程:玩转IPhone客户端和Web服务端交互(客户端)实践

    说到ios的应用开发,我们不能不提到web server服务端,如果没有服务端的支持,ios应用开发就没有多大意义了,因为从事过手机开发的朋友都知道(Android也一样),大量复杂业务的处理和数据库 ...

  4. 使用DWR实现JS调用服务端Java代码

    DWR简介 DWR全称Direct Web Remoting,是一款非常优秀的远程过程调用(Remote Procedure Call)框架,通过浏览器提供的Ajax引擎实现在前端页面的JS代码中调用 ...

  5. Android客户端与PHP服务端交互(一)---框架概述

    背景 作为一个普通上班族,总是想做一些自认为有意义的事情,于是乎准备成立一个工作室,尽管目前正在筹备阶段,但是之前有些朋友提出一些需求的时候,我发现自己的能力还是有限,直到最近和一些技术牛朋友聊起这事 ...

  6. java工具类(一)之服务端java实现根据地址从百度API获取经纬度

    服务端java实现根据地址从百度API获取经纬度 代码: package com.pb.baiduapi; import java.io.BufferedReader; import java.io. ...

  7. 6-1 建立客户端与zk服务端的连接

    6-1 建立客户端与zk服务端的连接 zookeeper原生java api使用 会话连接与恢复; 节点的增删改查; watch与acl的相关操作; 导入jar包;

  8. android客户端app和服务端交互token的作用

    Android客户端和服务端如何使用Token和Session niceheart关注1人评论34644人阅读2014-09-16 16:38:44   对于初学者来说,对Token和Session的 ...

  9. XFire客户端调用CXF服务端(四)

    前面章节:http://www.cnblogs.com/xiehongwei/p/8082337.html 已经开发出了CXF服务端,现在用XFire开发客户端调用CXF服务端,代码如下: impor ...

随机推荐

  1. C#网络编程基本字段---IPAddress、IPEndPoint

    命名空间: using System.Net; PAddress类提供了对IP地址的转换.处理等功能.其Parse方法可将IP地址字符串转换为IPAddress实例. 如:IPAddress ip = ...

  2. C++ 头文件保护符

    头文件保护符有什么作用? 在C++中我们写头文件时经常需要#include来包含其他头文件.头文件定义的实体经常使用其他头文件的内容,有时候会出现一个头文件被多次包含进同一源文件. 例如:一个头文件中 ...

  3. Linux make命令详解

    在linux环境下的工作,免不了需要经常编译C/C++源代码,所以make命令是我们经常都会用到的.当然make工具不一定针对C代码,它也可以维护其他各种代码,详见:man make    在列举其详 ...

  4. 关于gsl库出现access violation 0X00000005问题的解决方法

    gsl即GNU SCIENCE LIBRARY是一个强大c/c++的数值计算函数库. 在使用这一库出现access violation 0X00000005问题,尝试方法一在project->C ...

  5. 一道面试题:C++相比C#或者java的优势到底在哪里

    被问到了这样一道面试题,当时就懵了,内心一直觉得C++肯定在很多方面要比C#或者java要牛b的. 但是真的不知道怎么回答. 问题是:你以前一直做得是.NET相关项目,现在为什么找C++开发相关工作呢 ...

  6. Linux服务器中OpenSSH的源码编译与升级

                      Linux服务器中OpenSSH的源码编译与升级 https://www.oschina.net/question/12_7383    

  7. vim 源码分析

    vim 源码分析 http://bbs.csdn.net/topics/230031469 Ver7.1  晕.看不明白很正常.  7.1已经很大了.  支持了太多东西. 代码行数那么多(源码压缩了都 ...

  8. 使用Github官方提供的gitignore过滤Git提交的文件

    https://github.com/github/gitignore 在Gitignore项目主页找到VisualStudio.gitignore 下载后放到自己项目根目录的.vs文件夹提交就可以在 ...

  9. 【bzoj2212&3702】二叉树

    线段树合并入门题. 分别计算左子树的逆序对,右子树的逆序对,合并的时候计算贡献. #include<bits/stdc++.h> #define N 8000005 using names ...

  10. 回车和换行有什么区别?我们平时按下的Enter键是回车还是换行?

    来源:http://www.52rd.com/blog/Detail_RD.Blog_imjacob_12317.html -------------------------------------- ...