加密方式 AES

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

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc-portlet</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>3.2.5.RELEASE</version>
            <scope>test</scope>
        </dependency>

这个是原理图

在spring做如下 配置。

    <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
        <property name="order" value="0" />
    </bean>
    <bean class="com.sifude.youlife.spring.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        
        <property name="messageConverters">
            <list>
                <ref bean="jsonHttpMessageConverter" />
                <ref bean="stringHttpMessageConverter" />
                <!-- <ref bean="marshallingHttpMessageConverter" /> -->
            </list>
        </property>
    </bean>
    <bean id="stringHttpMessageConverter"
        class="org.springframework.http.converter.StringHttpMessageConverter">
        <constructor-arg value="UTF-8" />
        <property name="supportedMediaTypes">
            <value>text/html;charset=UTF-8</value>
        </property>
    </bean>
    <bean id="jsonHttpMessageConverter"
        class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
                <value>application/json;charset=UTF-8</value>
            </list>
        </property>
    </bean>

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

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<MultipartFile> 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)
@Documented
public @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);
        }
    } }

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

Spring 接口参数加密传输的更多相关文章

  1. 如何写出安全的API接口?接口参数加密签名设计思路

    开发中经常用到接口,尤其是在面向服务的soa架构中,数据交互全是用的接口. 几年以前我认为,我写个接口,不向任何人告知我的接口地址,我的接口就是安全的,现在回想真是too young,too simp ...

  2. 如何写出安全的 API 接口?接口参数加密签名设计思路

    原文链接:http://blog.csdn.net/ma_jiang/article/details/53636840

  3. 如何写出安全的API接口(参数加密+超时处理+私钥验证+Https)- 续(附demo)

    上篇文章说到接口安全的设计思路,如果没有看到上篇博客,建议看完再来看这个. 通过园友们的讨论,以及我自己查了些资料,然后对接口安全做一个相对完善的总结,承诺给大家写个demo,今天一并放出. 对于安全 ...

  4. 基于RequestBodyAdvice和ResponseBodyAdvice来实现spring中参数的加密和解密

    在日常开发中,有时候我们经常需要和第三方接口打交道,有时候是我们调用别人的第三方接口,有时候是别人在调用我们的第三方接口,那么为了调用接口的安全性,一般都会对传输的数据进行加密操作,如果每个接口都由我 ...

  5. 分享如何使用PHP将URL地址参数进行加密传输提高网站安全性

    大家在使用PHP进行GET或POST提交数据时,经常会在URL带着参数进行传递,比如www.mdaima.com/get.php?id=1&page=5,这里就将id编号和page页码进行了参 ...

  6. Spring Boot 之:接口参数校验

    Spring Boot 之:接口参数校验,学习资料 网址 SpringBoot(八) JSR-303 数据验证(写的比较好) https://qq343509740.gitee.io/2018/07/ ...

  7. java 调用Spring接口上传文件及其他参数填充

    第一步:在Spring配置中添加以下内容 <!-- 配置MultipartResolver 用于文件上传 使用spring的CommosMultipartResolver --> < ...

  8. spring 接口校验参数(自定义注解)

    1. 注解类 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.l ...

  9. Spring Boot实现通用的接口参数校验

    Spring Boot实现通用的接口参数校验 Harries Blog™ 2018-05-10 2418 阅读 http ACE Spring App API https AOP apache IDE ...

随机推荐

  1. spring-cloud-feign负载均衡组件

    Feign简介: Feign是一个声明式的Web服务客户端,使用Feign可使得Web服务客户端的写入更加方便.它具有可插拔注释支持,包括Feign注解和JAX-RS注解.Feign还支持可插拔编码器 ...

  2. 通过GIT_COMMIT进行代码回滚

    首先需要安装插件:conditional-buildstep A buildstep wrapping any number of other buildsteps, controlling thei ...

  3. eclipse如何更换工作空间

    关于工作空间的更换,小生也操作较少,今天做个记录并分享给大家. 1.找到文件——更换工作空间——其他 2.选择自己要更换的工作空间点击确定即可.

  4. 简单测试Elasticsearch 7.0

    发现不同的地方 1.创建index  (注意:7.0版本之前mappings中需要增加_doc,7.0版之后已去掉) PUT http://10.10.x.x:9200/test 2.Elastics ...

  5. git20181122

    git 在线编辑器 http://www.mdeditor.com/git add commit diff log status 代码撤消 # git https://github.com/gyz41 ...

  6. MyCat分片规则--笔记(二)

    概述 myCat实现分库分表的策略,对数据量的处理带来很大的便利,这里主要整理下MyCat的使用以及常用路由算法,针对MyCat里面的事务.集群后续再做整理:另外内容整理,不免会参考技术大牛的博客,内 ...

  7. 031 一次全面的java复习

    一:相关概念 1.面向对象的三个特征 封装,继承,多态,这个应该是人人皆知,有时候也会加上抽象. 2.多态的好处 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性.简单的说 ...

  8. IntelliJ IDE 基础经验备案

    1.配置本地的JAVA环境 2.配置本地安装的Maven环境 详情 1.配置本地的JAVA环境 准备: 本地已经安装java环境,目录:C:\Program Files\Java\jdk1.8.0_1 ...

  9. 第二项目AIaisell(易销宝)

    一.什么是报表 向上级报告情况的表格.简单的说:报表就是用表格.图表等格式来动态显示数据,可以用公式表示为:“报表 = 多样的格式 + 动态的数据” 表格:详细数据 图表: 直观 二.表格数据展示 2 ...

  10. 元素定位-XPATH定位方法总结

    1.Xpath定位方法探讨 xpath是比较常用的一种定位元素的方式,因为它很方便,缺点是,消耗系统性能.如果Xpath使用的比较好,几乎可以定位到任何页面元素,而且受页面变化影响较小. 1.1.什么 ...