<返回更多

SpringBoot:接口加密解密设计

2023-03-03  今日头条  摆脱格子衫
加入收藏

 

在Spring Boot中实现接口数据的加密和解密,可以使用对称加密算法,例如AES算法,将请求参数和响应结果进行加密和解密。以下是一种示例实现方案:

  1. 添加依赖

在pom.xml文件中添加以下依赖:

<dependency>
    <groupId>JAVAx.crypto</groupId>
    <artifactId>jce</artifactId>
    <version>1.0.2</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.68</version>
</dependency>
  1. 实现加密和解密工具类

创建AesUtil工具类,实现AES加密和解密方法:

public class AesUtil {
    // AES算法使用CBC模式和PKCS7Padding填充方式
    private static final String AES_ALGORITHM = "AES/CBC/PKCS7Padding";
    // AES算法的密钥算法是AES
    private static final String AES_KEY_ALGORITHM = "AES";
    // 密钥长度为16个字节,即128位
    private static final String AES_KEY = "1234567812345678";
    // 初始化向量长度也为16个字节,即128位
    private static final String AES_IV = "1234567890123456";

    // AES加密方法
    public static String encrypt(String content) {
        try {
            byte[] keyBytes = AES_KEY.getBytes();
            SecretKeySpec keySpec = new SecretKeySpec(keyBytes, AES_KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM, "BC");
            IvParameterSpec ivSpec = new IvParameterSpec(AES_IV.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
            byte[] encrypted = cipher.doFinal(content.getBytes("UTF-8"));
            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // AES解密方法
    public static String decrypt(String content) {
        try {
            byte[] keyBytes = AES_KEY.getBytes();
            SecretKeySpec keySpec = new SecretKeySpec(keyBytes, AES_KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM, "BC");
            IvParameterSpec ivSpec = new IvParameterSpec(AES_IV.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            byte[] encrypted = Base64.getDecoder().decode(content);
            byte[] decrypted = cipher.doFinal(encrypted);
            return new String(decrypted, "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
  1. 实现请求参数和响应结果加密解密拦截器

创建AesEncryptInterceptor拦截器,用于对请求参数进行加密和对响应结果进行解密:

public class AesEncryptInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 对请求参数进行加密
        String content = request.getParameter("content");
        if (StringUtils.isNotBlank(content)) {
            String encryptedContent =AesUtil.encrypt(content);
            request.setAttribute("content", encryptedContent);
        }
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 对响应结果进行解密
        Object result = request.getAttribute("result");
        if (result != null && result instanceof String) {
            String decryptedResult = AesUtil.decrypt((String) result);
            request.setAttribute("result", decryptedResult);
        }
        super.postHandle(request, response, handler, modelAndView);
    }
}
  1. 配置拦截器

在WebMvcConfigurer配置类中添加AesEncryptInterceptor拦截器:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AesEncryptInterceptor());
    }
}

完成以上步骤后,接口数据的加密和解密功能就已经实现了。以下是示例代码:

@RestController
@RequestMApping("/api")
public class ApiController {
    @GetMapping("/hello")
    public String hello(@RequestParam("content") String content) {
        return "Hello, " + content;
    }
}

当发送请求时,请求参数content会被拦截器加密,请求被处理后返回的结果也会被拦截器解密,从而保证接口数据的安全性。

 

如果请求参数在body中,则需要在拦截器中读取请求体并进行加密,同时在控制器方法中也需要读取加密后的请求体并进行解密。

以下是修改后的代码示例:

  1. 定义AesEncryptInterceptor拦截器
public class AesEncryptInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 对请求体进行加密
        String requestBody = HttpHelper.getBodyString(request);
        if (StringUtils.isNotBlank(requestBody)) {
            String encryptedBody = AesUtil.encrypt(requestBody);
            HttpHelper.setBodyString(request, encryptedBody);
        }
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 对响应结果进行解密
        Object result = request.getAttribute("result");
        if (result != null && result instanceof String) {
            String decryptedResult = AesUtil.decrypt((String) result);
            request.setAttribute("result", decryptedResult);
        }
        super.postHandle(request, response, handler, modelAndView);
    }
}
  1. 定义HttpHelper类
public class HttpHelper {
    public static String getBodyString(final ServletRequest request) throws IOException {
        InputStream inputStream = null;
        StringBuilder sb = new StringBuilder();
        try {
            inputStream = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return sb.toString();
    }

    public static void setBodyString(final ServletRequest request, String body) {
        try {
            ServletInputStream inputStream = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            String oldBody = sb.toString();
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
            Field field = inputStream.getClass().getDeclaredField("in");
            field.setAccessible(true);
            field.set(inputStream, byteArrayInputStream);
            request.setAttribute("oldBody", oldBody);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  1. 在控制器中解密请求体
@RestController
@RequestMapping("/api")
public class ApiController {
    @PostMapping("/hello")
    public String hello(@RequestBody String requestBody) {
        // 解密请求体
        String decryptedRequestBody = AesUtil.decrypt(requestBody);
        // 处理请求
        // ...
        // 返回响应结果
        String responseBody = "Hello, " + decryptedRequestBody;
        // 加密响应结果
        return AesUtil.encrypt(responseBody);
    }
}
  1. 配置拦截器

在WebMvcConfigurer配置类中添加AesEncryptInterceptor拦截器:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AesEncryptInterceptor());
    }
}

完成以上步骤后,接口数据的加密和解密功能

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>