客户端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 ...
随机推荐
- 51Nod 1081前缀和
#include <iostream> #include <stdio.h> using namespace std; ]; ]; int main() { int n; ci ...
- PHP文件操作函数一
<?php/*Created on 2013-6-26*///判断文件的类型echo filetype("array.php")."<br />&quo ...
- bzoj 1096 斜率优化DP
首先比较容易的看出来是DP,w[i]为前i个工厂的最小费用,那么w[i]=min(w[j-1]+cost(j,i))+c[i],但是这样是不work的,复杂度上明显过不去,这样我们考虑优化DP. 设A ...
- 如何保护自己的windows系统
最近一段时间给windows做加固防护,积累了几个小工具. 1.杀毒:火绒+火绒剑,windows10 自带的杀毒Windows Defender 2.日志记录: sysmon sysmon用来 ...
- vim 源码分析
vim 源码分析 http://bbs.csdn.net/topics/230031469 Ver7.1 晕.看不明白很正常. 7.1已经很大了. 支持了太多东西. 代码行数那么多(源码压缩了都 ...
- Selenium2+python自动化55-unittest之装饰器(@classmethod)【转载】
前言 前面讲到unittest里面setUp可以在每次执行用例前执行,这样有效的减少了代码量,但是有个弊端,比如打开浏览器操作,每次执行用例时候都会重新打开,这样就会浪费很多时间. 于是就想是不是可以 ...
- java的maven项目(三)私服的搭建(windows版)
1 私服 nexus 安装nexus 启动服务 启动失败的解决方法: 登录nexus 用户名/密码 admin/admin123 仓库类型 Virtual 虚拟仓库 Proxy 代 ...
- pytest学习(1)
pytest是python的一个测试框架,主要是用来进行一些小的测试. 在pycharm中,缺省用的是unittest,这里说明如何设置为pytest. 当然,第一部是安装pytest pip3 in ...
- hdu 5190(水题)
Go to movies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- jquery事件之select选中事件
根据select下拉列表选中的不同选项执行不同的方法,工作中经常会用到,这里就要用到Jquery的select选中事件 这里给select加一个叫label_id的id,然后通过id选择器找到这个节点 ...