博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring 实现 接口 加密。
阅读量:6935 次
发布时间:2019-06-27

本文共 10548 字,大约阅读时间需要 35 分钟。

hot3.png

加密方式 AES

spring jar 包 pom.xml配置(注意版本)

        
            
org.springframework
            
spring-core
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-jdbc
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-orm
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-context
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-context-support
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-beans
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-aspects
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-aop
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-webmvc
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-web
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-tx
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-webmvc-portlet
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-oxm
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-jms
            
3.2.5.RELEASE
        
        
            
org.springframework
            
spring-test
            
3.2.5.RELEASE
            
test
        

这个是原理图

在spring做如下 配置。

    
    
        
        
                
            
                
                
                
            
                
        
        
            
text/html;charset=UTF-8
                
        
            
                
text/html;charset=UTF-8
                
application/json;charset=UTF-8
            
            

可以发现com.sifude.youlife.spring.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter这个类就是我们自己写的。从spring里面拷贝出如下几个类

110640_SfrG_2288185.png

RequestParamMethodArgumentResolver对每个参数进行了拦截,然后在resolveName方法进行处理,因此我们只要

重写RequestParamMethodArgumentResolver中的resolveName方法即可

    @Override    protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest webRequest) throws Exception {        Object arg;        HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);        MultipartHttpServletRequest multipartRequest =            WebUtils.getNativeRequest(servletRequest, MultipartHttpServletRequest.class);        if (MultipartFile.class.equals(parameter.getParameterType())) {            assertIsMultipartRequest(servletRequest);            Assert.notNull(multipartRequest, "Expected MultipartHttpServletRequest: is a MultipartResolver configured?");            arg = multipartRequest.getFile(name);        }        else if (isMultipartFileCollection(parameter)) {            assertIsMultipartRequest(servletRequest);            Assert.notNull(multipartRequest, "Expected MultipartHttpServletRequest: is a MultipartResolver configured?");            arg = multipartRequest.getFiles(name);        }        else if ("javax.servlet.http.Part".equals(parameter.getParameterType().getName())) {            assertIsMultipartRequest(servletRequest);            arg = servletRequest.getParameter(name);        }        else {            arg = null;            if (multipartRequest != null) {                List
 files = multipartRequest.getFiles(name);                if (!files.isEmpty()) {                    arg = (files.size() == 1 ? files.get(0) : files);                }            }            if (arg == null) {                boolean isEnc = false;                if (null != parameter.getMethod().getAnnotation(EncRequest.class)) {                    isEnc = true;                }                if (isEnc) {// 数据需要加密的情况                    String content = servletRequest.getParameter("content");                    if (null != content) {                        content = AESUtil.decrypt(content);                        ObjectMapper mapper = new ObjectMapper(); // can reuse, share                        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);// 忽略未知元素                        Object o = mapper.readValue(content, HashMap.class).get(name);                        if(o instanceof String[]) {                            String[] paramValues = (String[]) o;                            if (paramValues != null) {                                arg = paramValues.length == 1 ? paramValues[0] : paramValues;                            }                        } else {                            arg = o;                        }                    }                } else {                    String[] paramValues = webRequest.getParameterValues(name);                    if (paramValues != null) {                        arg = paramValues.length == 1 ? paramValues[0] : paramValues;                    }                }            }        }        return arg;    }
其他1个注解和加密算法
package com.sifude.annotations;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface EncRequest {}
package com.sifude.tool.util;import java.io.UnsupportedEncodingException;import java.util.Random;import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import org.apache.commons.codec.binary.Base64;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.sifude.tool.util.entity.Constant;/** * AES加解密算法 * key:每次登陆动态随机生成(大小写字母和数字组成),并保存在session中 * 此处使用AES-128-CBC加密模式,key需要为16位 */public class AESUtil {    private static Logger log = LoggerFactory.getLogger(FileUtil.class);        public static boolean isAES = Constant.AES.ISAES;    public static String sKey = Constant.AES.SKEY;        // 加密    public static String encrypt(String sSrc) throws Exception {                if(!isAES) {            return sSrc;        }        if (sKey == null) {            //System.out.print("Key为空null");            return null;        }        // 判断Key是否为16位        if (sKey.length() != 16) {            //System.out.print("Key长度不是16位");            return null;        }        byte[] raw = sKey.getBytes();        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// "算法/模式/补码方式"        IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);        //加密前要进行编码,否则js无法解码        byte[] encrypted = cipher.doFinal(sSrc.getBytes("UTF-8"));        return Base64.encodeBase64String(encrypted);// 此处使用BAES64做转码功能,同时能起到2次加密的作用。    }    // 解密    public static String decrypt(String sSrc) throws Exception {        if(!isAES) {            return sSrc;        }        // 判断Key是否正确        if (sKey == null) {            //System.out.print("Key为空null");            return null;        }        // 判断Key是否为16位        if (sKey.length() != 16) {            //System.out.print("Key长度不是16位");            return null;        }        byte[] raw = sKey.getBytes("ASCII");        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");        IvParameterSpec iv = new IvParameterSpec("0102030405060708"                .getBytes());        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);        byte[] encrypted1 = Base64.decodeBase64(sSrc);// 先用bAES64解密        //System.out.println(encrypted1.length);        byte[] original = cipher.doFinal(encrypted1);        String originalString = new String(original);        return originalString;    }    // 生成随机密锁    public static String getKey(int length) {        StringBuffer sb = new StringBuffer();        Random random = new Random();        // 参数length,表示生成几位随机数        for (int i = 0; i < length; i++) {            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";            // 输出字母还是数字            if ("char".equalsIgnoreCase(charOrNum)) {                // 输出是大写字母还是小写字母                int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;                sb.append((char) (random.nextInt(26) + temp));            } else if ("num".equalsIgnoreCase(charOrNum)) {                sb.append(String.valueOf(random.nextInt(10)));            }        }        try {            return new String(sb.toString().getBytes(), "UTF-8");        } catch (UnsupportedEncodingException e) {            log.error(e.getMessage(), e);        }        return "mapabc2014214yxj";    }    public static void main(String[] args) {        //AES.sKey = getKey(16);        AESUtil.isAES = true;        try {            //String str = AES.encrypt("你好1.2#3:4//5_6,1 2&3?4a/bc5=6");            //String str = AES.encrypt("{\"account\":\"ez\",\"password\":\"123456\"}");            String str = AESUtil.encrypt("{\"cityId\":\"110000\",\"cityType\":\"1\"}");            System.out.println(str);            String str1 = AESUtil.decrypt(str);            System.out.println(str1);        } catch (Exception e) {            log.error(e.getMessage(), e);        }    }}

这样功能就实现了,欢迎大家一期交流。

转载于:https://my.oschina.net/u/2288185/blog/488552

你可能感兴趣的文章
使用 nginx 同域名下部署多个 vue 项目,并使用反向代理
查看>>
Python基本数据类型之元组
查看>>
LeetCode-数组-删除有序数组重复元素
查看>>
我所理解的原型&原型链
查看>>
工作三年,我要如何提升Java技术 | 粉丝提问
查看>>
JavaScript 如何使用闭包
查看>>
React 教程:快速上手指南
查看>>
6 个理由,让我不顾一切撑腰 Python!
查看>>
[ 一起学React系列 -- 11 ] React-Router4 (1)
查看>>
在Java中使用redisTemplate操作缓存
查看>>
Generator函数的语法以及异步的应用
查看>>
使用 qrcodejs 生成二维码的几个问题
查看>>
ES6-Promise对象
查看>>
记录一次面试题
查看>>
Flutter Exception降到万分之几的秘密
查看>>
Fiddler抓取数据并分析(完整的配置教程)
查看>>
Keras入门(一)搭建深度神经网络(DNN)解决多分类问题
查看>>
【思维导图-索引篇】搞定数据库索引就是这么简单
查看>>
Kotlin如何避免“!!”(非空断言)
查看>>
我理解的 iOS 与 Android 的区别
查看>>