客户端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");
}
客户端JavaScript加密数据,服务端Java解密数据的更多相关文章
- 基于NIO的同步非阻塞编程完整案例,客户端发送请求,服务端获取数据并返回给客户端数据,客户端获取返回数据
这块还是挺复杂的,挺难理解,但是多练几遍,多看看研究研究其实也就那样,就是一个Selector轮询的过程,这里想要双向通信,客户端和服务端都需要一个Selector,并一直轮询, 直接贴代码: Ser ...
- java版gRPC实战之六:客户端动态获取服务端地址
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- IOS开发系列之阿堂教程:玩转IPhone客户端和Web服务端交互(客户端)实践
说到ios的应用开发,我们不能不提到web server服务端,如果没有服务端的支持,ios应用开发就没有多大意义了,因为从事过手机开发的朋友都知道(Android也一样),大量复杂业务的处理和数据库 ...
- 使用DWR实现JS调用服务端Java代码
DWR简介 DWR全称Direct Web Remoting,是一款非常优秀的远程过程调用(Remote Procedure Call)框架,通过浏览器提供的Ajax引擎实现在前端页面的JS代码中调用 ...
- Android客户端与PHP服务端交互(一)---框架概述
背景 作为一个普通上班族,总是想做一些自认为有意义的事情,于是乎准备成立一个工作室,尽管目前正在筹备阶段,但是之前有些朋友提出一些需求的时候,我发现自己的能力还是有限,直到最近和一些技术牛朋友聊起这事 ...
- java工具类(一)之服务端java实现根据地址从百度API获取经纬度
服务端java实现根据地址从百度API获取经纬度 代码: package com.pb.baiduapi; import java.io.BufferedReader; import java.io. ...
- 6-1 建立客户端与zk服务端的连接
6-1 建立客户端与zk服务端的连接 zookeeper原生java api使用 会话连接与恢复; 节点的增删改查; watch与acl的相关操作; 导入jar包;
- android客户端app和服务端交互token的作用
Android客户端和服务端如何使用Token和Session niceheart关注1人评论34644人阅读2014-09-16 16:38:44 对于初学者来说,对Token和Session的 ...
- XFire客户端调用CXF服务端(四)
前面章节:http://www.cnblogs.com/xiehongwei/p/8082337.html 已经开发出了CXF服务端,现在用XFire开发客户端调用CXF服务端,代码如下: impor ...
随机推荐
- redis连接池自动释放
http://blog.itpub.net/29485627/viewspace-1977880/
- bzoj1503 郁闷的出纳员 splay版
自己yy的写法 可能有点奇怪吧 详情看代码 还是蛮短的 #include<cstdio> #include<cstring> #include<algorithm> ...
- [bzoj3532][Sdoi2014]Lis——拆点最小割+字典序+退流
题目大意 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若 干项,使得4的最长上升子序列长度减少至少1,且付出的代价之和最小,并输出方案. 如果有多种方案,请输出将删去项的附加属性 ...
- MongoDB 聚合(管道与表达式)
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果.有点类似sql语句中的 count(*). aggregate() 方法 MongoDB中 ...
- mongodb的集合操作
MongoDB 创建集合 1.手动创建: 语法格式: db.createCollection(name, options) 参数说明: name: 要创建的集合名称 options: 可选参数, 指定 ...
- 利用opencv自带源码,调试摄像头做人脸检测
本文为原创作品,转载请注明出处 欢迎关注我的博客:http://blog.csdn.net/hit2015spring 和 http://www.cnblogs.com/xujianqing/ 作者: ...
- Oracle exp
--导出表exp userid=hr/oracle123 tables=employees direct=y file=/u01/employees.dmp log=/u01/employees.lo ...
- 【bzoj4272】筐子放球
看题解会的系列…… 详细解释先坑着,以后补…… #include<bits/stdc++.h> #define N 200005 using namespace std; ,tot=,cn ...
- eclipse启动几秒后报错 (一闪而过)
eclipse启动报错,让查看.metadata/.log日志 1 !SESSION 2013-09-23 17:28:28.484 ------------------------------- ...
- docker从零开始网络(二)桥接网络
使用桥接网络 在网络方面,桥接网络是链路层设备,它在网络段之间转发流量.桥接网络可以是硬件设备或在主机内核中运行的软件设备. 就Docker而言,桥接网络使用软件桥接器,该软件桥接器允许连接到同一桥接 ...