java实现后端接口加密
来源:互联网 发布:淘宝旺旺怎么改名字 编辑:程序博客网 时间:2024/06/08 17:53
思想:先给大家讲讲我们如何来实现接口加密,我们主要通过签名验证的方式来实现接口加密,前端给后端接口传参数时
先用aes加密,生成一个sign签名,后端写一个拦截器对其进行签名验证,后端接收到参数后,也通过同样的方法
对其参数加密生成一个sign,两者相对比,如何相同则签名成功! 自己在加密生成签名时,自己也可以定义一系列规则
,比如,我这里在加密前先对其进行排序后进行加密。
代码如下:
html代码
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE><html><head> <base href="<%=basePath%>"> <title>接口验证</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/bootstrap.min.css"> <script src="${pageContext.request.contextPath}/js/jquery-1.10.1.js"></script> <script src="${pageContext.request.contextPath}/js/crypto-js.js"></script> <script src="${pageContext.request.contextPath}/js/aes.js"></script> <script src="${pageContext.request.contextPath}/js/mode-ecb.js"></script> <script src="${pageContext.request.contextPath}/js/verify.js"></script> <script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script></head><body><div class="container"> <div class="row"> <form class="form-horizontal" role="form" id="form"> <div class="form-group"> <label for="firstname" class="col-sm-2 control-label">名字</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" id="firstname" placeholder="请输入名字"> </div> </div> <div class="form-group"> <label for="sex" class="col-sm-2 control-label">性别</label> <div class="col-sm-10"> <input type="text" class="form-control" name="sex" id="sex" placeholder="请输入名字"> </div> </div> <div class="form-group"> <label for="age" class="col-sm-2 control-label">年龄</label> <div class="col-sm-10"> <input type="text" class="form-control" name="age" id="age" placeholder="请输入名字"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="button" onclick="dl()" class="btn btn-default">登录</button> </div> </div> </form> </div></div></body></html><script>
js代码:
var map = {};// function Encrypt(word){ //加密// var key = CryptoJS.enc.Utf8.parse("abcdefgabcdefg12");// //console.log("key:" + key);// var srcs = CryptoJS.enc.Utf8.parse(word);// //console.log("srcs:" + srcs);// var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});// return encrypted.toString();// }// function Decrypt(word){ //解密// var key = CryptoJS.enc.Utf8.parse("abcdefgabcdefg12");//// var decrypt = CryptoJS.AES.decrypt(word, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});// return CryptoJS.enc.Utf8.stringify(decrypt).toString();// }
* 以上注释代码为加密和解密代码,这个我们是不能暴露在网页上面的,如果暴露在上面
别人知道你的key值后就可以对你的加密结果进行解密了,目前就只找到通过js混淆来解决,
以下一行就是上面注释代码通过混淆后的代码
function Encrypt(ZWeAf1){ var M2 = CryptoJS["\x65\x6e\x63"]["\x55\x74\x66\x38"]["\x70\x61\x72\x73\x65"]("\x61\x62\x63\x64\x65\x66\x67\x61\x62\x63\x64\x65\x66\x67\x31\x32"); var JMCt_3 = CryptoJS["\x65\x6e\x63"]["\x55\x74\x66\x38"]["\x70\x61\x72\x73\x65"](ZWeAf1); var fQihKY4 = CryptoJS["\x41\x45\x53"]["\x65\x6e\x63\x72\x79\x70\x74"](JMCt_3, M2, {mode:CryptoJS["\x6d\x6f\x64\x65"]["\x45\x43\x42"],padding: CryptoJS["\x70\x61\x64"]["\x50\x6b\x63\x73\x37"]}); return fQihKY4["\x74\x6f\x53\x74\x72\x69\x6e\x67"]();}function Decrypt(GflP6){ var TpV7 = CryptoJS["\x65\x6e\x63"]["\x55\x74\x66\x38"]["\x70\x61\x72\x73\x65"]("\x61\x62\x63\x64\x65\x66\x67\x61\x62\x63\x64\x65\x66\x67\x31\x32"); var ksLf_V8 = CryptoJS["\x41\x45\x53"]["\x64\x65\x63\x72\x79\x70\x74"](GflP6, TpV7, {mode:CryptoJS["\x6d\x6f\x64\x65"]["\x45\x43\x42"],padding: CryptoJS["\x70\x61\x64"]["\x50\x6b\x63\x73\x37"]}); return CryptoJS["\x65\x6e\x63"]["\x55\x74\x66\x38"]["\x73\x74\x72\x69\x6e\x67\x69\x66\x79"](ksLf_V8)["\x74\x6f\x53\x74\x72\x69\x6e\x67"]();}function dl(form) { var name = $("#firstname").val(); var sex = $("#sex").val(); var age = $("#age").val(); map["name"] = name; map["age"] = age; map["sex"] = sex; map["xm-name"]="SSM"; map["dev-name"]="spf"; var arr2 = sortToMap(); var str = sign(arr2) console.log(str); $.ajax({ url:'/sign', type:'POST', data :{"name":name,"age":age,"sex":sex,"sign":str}, dataType : 'json', success:function (res) { console.log(res); if (res.code == 200) { alert("签名成功"); } } });}//对参数拼接成 XXX=XXX&XXX==XXXX 字符串的形式 后再进行加密function sign(arr2) { var str = ""; for (var i = 0; i < arr2.length; i++){ if (map[arr2[i]] == null || map[arr2[i]] == "" || map[arr2[i]] == undefined) { continue; } str += arr2[i] + "=" + map[arr2[i]]+"&"; } str = str.substring(0, str.length - 1); console.log(str); str = Encrypt(str); return str;}// 对参数排序function sortToMap() { var arr=new Array() for(var key in map) { arr.push(key); } arr.sort(); return arr;}
后端代码
拦截器代码:
package com.utils.interceptor;import com.controller.mail.MailController;import com.utils.BaseUtils;import com.utils.common.AES;import org.apache.log4j.Logger;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.Map;/** * Created by Administrator on 2017/6/16 0016. */public class SignInterceptor implements HandlerInterceptor { private static final Logger logger = Logger.getLogger(MailController.class); public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception { Map<String, Object> map = BaseUtils.getParamMap(request); Object osign = map.get("sign"); if (osign == null) { return false; } map.put("xm-name","SSM"); map.put("dev-name","spf"); map.remove("sign"); String str = BaseUtils.createLinkString(map); String key = "abcdefgabcdefg12"; String sign = AES.encryptToBase64(str,key); if (!sign.equals(osign.toString())) { logger.info("===================>签名验证失败<========================"); return false; } return true; } public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { }}
用到的工具类代码
/** * 获取request 中的参数,以map形式返回 * @param request * @return */public static Map<String, Object> getParamMap(ServletRequest request) { //Assert.notNull(request,"参数不能为空"); Map<String, Object> map = Maps.newHashMap(); Enumeration<String> en = request.getParameterNames(); while (en.hasMoreElements()) { String name = en.nextElement(); String[] values = request.getParameterValues(name); if (values == null || values.length == 0) { continue; } String value = values[0]; if (value != null) { map.put(name, value); } } return map;}
/** * 把数组所有元素,按字母排序,然后按照“参数=参数值”的模式用“&”字符拼接成字符串 * * @param params * 需要签名的参数 * @return 签名的字符串 */public static String createLinkString(Map<String, Object> params) { List<String> keys = Lists.newArrayList(params.keySet().iterator()); Collections.sort(keys); StringBuilder signStr = new StringBuilder(); for (String key : keys) { if (!checkNotNull(params.get(key).toString())) { continue; } signStr.append(key).append("=").append(params.get(key)).append("&"); } return signStr.deleteCharAt(signStr.length() - 1).toString();}/**
*加密
*/
public static String encryptToBase64(String data, String key){ try { byte[] valueByte = encrypt(data.getBytes(CHAR_ENCODING), key.getBytes(CHAR_ENCODING)); return new String(Base64.encodeBase64(valueByte,false)); } catch (UnsupportedEncodingException e) { throw new RuntimeException("encrypt fail!", e); } }
现在就来运行查看一下结果吧:
1.启动项目
点击登录:查看结果
这里我们在拦截器里就可以看见签名了,1 表示前端传过来的签名,2表示后端签名,签名相同就返回true,进入action,不相同就返回false,请求中断
参看结果
成功!
我这里写的测试代码,比较草率,建议大家把 js 加密,排序,组装为字符串等一些列代码提出来写在一个 js 文件里,然后在通过 js 混淆处理,
把混淆后的代码复制粘贴进去,把原来代码删除!
觉得有用请点个赞,谢谢!
阅读全文
4 0
- java实现后端接口加密
- java后端发布的接口数据是如何加密传输
- RSA前端JS加密,后端JAVA解密实现
- RSA前端JS加密,后端JAVA解密实现
- RSA前端JS加密,后端JAVA解密实现
- RESTful API实战笔记(接口设计及Java后端实现)
- spring实现接口加密
- 接口加密实现
- 从零开发一款APP 二、Java Web后端注册接口的实现
- java代码实现加密解密(MD5签名(同步接口))
- [Java Web]后端接口版本控制
- Java如何实现后端分页
- RSA实现JS前端加密,PHP后端解密
- RSA实现JS前端加密,PHP后端解密
- RSA实现JS前端加密,PHP后端解密
- JAVA APP——密码加密后端存储
- Java 前端加密传输后端解密以及验证码功能
- Java 前端加密传输后端解密以及验证码功能
- Java获取当前操作系统的信息
- kali 源更新
- apiCloud小结
- 逆向工程核心原理学习笔记(十三):分析abex' crackme #1 的延伸:将参数压入栈
- 数据结构实验——查找的有关操作
- java实现后端接口加密
- 逆向工程核心原理学习笔记(十四):栈帧1
- 浅谈java动态代理
- 本博客的主要更新已经迁至新站
- Git简明教程
- phpcms项目从本地上服务器。后台验证码失效,屏蔽验证码或者安装GD库就可以了
- 系统操作日志的实现原理
- 关于Kriging算法的总结及其在三维属性建模方面的应用(草稿)
- iOS捕捉截屏事件并展示截图