欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Boot 一個注解搞定加密 + 解密 + 簽名 + 驗簽(一文全解)

 更新時間:2025年09月20日 09:49:35   作者:半部論語  
本文介紹了一種基于Spring Boot 3.x的接口安全解決方案,通過自定義注解@ApiSecurity結(jié)合AOP切面,實現(xiàn)請求解密、驗簽、響應(yīng)加密及加簽的自動化處理,_springboot api aop 報文加解密

Spring Boot 一個注解搞定「加密 + 解密 + 簽名 + 驗簽」

本文基于 Spring Boot 3.x,通過一個自定義注解 + AOP,一行注解即可給任何 Controller 方法加上
請求解密 → 驗簽 → 響應(yīng)加密 → 加簽 的完整鏈路,并可直接拷貝到生產(chǎn)環(huán)境使用。

一、最終效果

@PostMapping("/order")
@ApiSecurity(decryptRequest = true, encryptResponse = true)   // ← 就這么一行
public OrderResp createOrder(@RequestBody OrderReq req) {
    return service.create(req);
}
  • 請求體:RSA 加密后的 AES 密鑰 + AES 加密后的業(yè)務(wù) JSON + 簽名
  • 框架自動完成 解密 → 驗簽 → 業(yè)務(wù)處理 → 響應(yīng)加密 → 加簽
  • 零侵入,老接口想加安全,貼一個注解即可。

二、傳輸對象

@Data
public class ApiSecurityParam {
    private String appId;      // 應(yīng)用標(biāo)識
    private String key;        // RSA 加密后的 AES 密鑰(Base64)
    private String data;       // AES 加密的業(yè)務(wù) JSON(Base64)
    private String sign;       // 簽名
    private String timestamp;  // 防重放
    private String nonce;      // 防重放
}

三、核心注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiSecurity {
    boolean decryptRequest()  default false; // 請求體是否解密
    boolean encryptResponse() default false; // 響應(yīng)體是否加密
    boolean sign()            default true;  // 是否驗簽/加簽
}

四、AOP 切面(RequestBodyAdvice + ResponseBodyAdvice)

同時解決 InputStream 只能讀一次 的問題。

4.1 解密 & 驗簽 RequestBodyAdvice

@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class DecryptRequestAdvice implements RequestBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Type targetType,
                            Class<? extends HttpMessageConverter<?>> converterType) {
        return methodParameter.hasMethodAnnotation(ApiSecurity.class)
                && methodParameter.getMethodAnnotation(ApiSecurity.class).decryptRequest();
    }
    @Override
    public Object handleEmptyBody(Object body, HttpInputMessage inputMessage,
                                  MethodParameter parameter, Type targetType,
                                  Class<? extends HttpMessageConverter<?>> converterType) {
        return body;
    }
    @SneakyThrows
    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage,
                                           MethodParameter parameter, Type targetType,
                                           Class<? extends HttpMessageConverter<?>> converterType) {
        String body = StreamUtils.copyToString(inputMessage.getBody(), StandardCharsets.UTF_8);
        ApiSecurityParam param = JSON.parseObject(body, ApiSecurityParam.class);
        // 1. 防重放校驗(timestamp、nonce)
        checkReplay(param);
        // 2. RSA 私鑰解密 AES 密鑰
        String aesKey = RSAUtil.decryptByPrivateKey(param.getKey(), RsaKeyHolder.PRIVATE_KEY);
        // 3. AES 解密業(yè)務(wù) JSON
        String json = AESUtil.decrypt(param.getData(), aesKey);
        // 4. 驗簽
        boolean ok = RSAUtil.verify(json + param.getTimestamp() + param.getNonce(),
                                    RsaKeyHolder.PUBLIC_KEY, param.getSign());
        if (!ok) throw new BizException("驗簽失敗");
        return new MappingJacksonInputMessage(new ByteArrayInputStream(json.getBytes()),
                                              inputMessage.getHeaders());
    }
}

4.2 加密 & 加簽 ResponseBodyAdvice

@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(MethodParameter returnType,
                            Class<? extends HttpMessageConverter<?>> converterType) {
        ApiSecurity anno = returnType.getMethodAnnotation(ApiSecurity.class);
        return anno != null && anno.encryptResponse();
    }
    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        String json = JSON.toJSONString(body);
        // 1. 隨機 AES 密鑰
        String aesKey = AESUtil.randomKey(128);
        // 2. AES 加密響應(yīng)
        String data = AESUtil.encrypt(json, aesKey);
        // 3. RSA 公鑰加密 AES 密鑰
        String encKey = RSAUtil.encryptByPublicKey(aesKey, RsaKeyHolder.PUBLIC_KEY);
        // 4. 生成簽名
        String sign = RSAUtil.sign(json, RsaKeyHolder.PRIVATE_KEY);
        ApiSecurityParam resp = new ApiSecurityParam();
        resp.setKey(encKey);
        resp.setData(data);
        resp.setSign(sign);
        resp.setTimestamp(String.valueOf(System.currentTimeMillis()));
        return resp;
    }
}

五、工具類速覽

  • RSAUtilencrypt/decrypt + sign/verify
  • AESUtilencrypt/decrypt 支持 PKCS5Padding
  • RsaKeyHolder:從 application.yml 或 KMS 讀取公私鑰

六、性能 & 安全小貼士

建議
對稱加密AES-128-CBC/PKCS5Padding
非對稱RSA-2048
防重放timestamp ±5 min + nonce 一次性
密鑰輪換每日定時任務(wù)刷新 RSA 密鑰對
性能AES 每次隨機 IV,RSA 只加密 128bit 密鑰,無壓力

七、小結(jié)

通過以上 一個注解 + 兩個 Advice,在 Spring Boot 中實現(xiàn) 企業(yè)級安全傳輸

  • 0 侵入:老接口貼注解即可
  • 高可擴展:支持 GET/POST、Header 傳參、自定義算法
  • 已落地:可直接封裝為 spring-boot-starter-security-api,全公司復(fù)用。

源碼示例已上傳 GitHub:
https://github.com/your-org/spring-boot-api-security-starter

到此這篇關(guān)于Spring Boot 一個注解搞定「加密 + 解密 + 簽名 + 驗簽」的文章就介紹到這了,更多相關(guān)Spring Boot注解加密 解密 簽名 驗簽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實現(xiàn)人機猜拳游戲

    Java實現(xiàn)人機猜拳游戲

    這篇文章主要為大家詳細介紹了Java實現(xiàn)人機猜拳游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • logback關(guān)閉某個包的日志操作

    logback關(guān)閉某個包的日志操作

    這篇文章主要介紹了logback關(guān)閉某個包的日志操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • SpringBoot實現(xiàn)PDF轉(zhuǎn)圖片的代碼示例

    SpringBoot實現(xiàn)PDF轉(zhuǎn)圖片的代碼示例

    在本文中,我們使用SpringBoot演示了如何將PDF文件轉(zhuǎn)換為一張或多張圖片,這些示例演示了如何使用Java編程語言與其他開源技術(shù)集成,以實現(xiàn)各種文件格式之間的轉(zhuǎn)換,感興趣的小伙伴跟著小編一起來看看吧
    2024-08-08
  • SpringCloud turbine監(jiān)控實現(xiàn)過程解析

    SpringCloud turbine監(jiān)控實現(xiàn)過程解析

    這篇文章主要介紹了SpringCloud turbine監(jiān)控實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • Java內(nèi)存模型的深入講解

    Java內(nèi)存模型的深入講解

    這篇文章主要給大家介紹了關(guān)于Java內(nèi)存模型的相關(guān)資料,我們常說的JVM內(nèi)存模式指的是JVM的內(nèi)存分區(qū),而Java內(nèi)存模式是一種虛擬機規(guī)范,需要的朋友可以參考下
    2021-07-07
  • IDEA 打開java文件對應(yīng)的class路徑的操作步驟

    IDEA 打開java文件對應(yīng)的class路徑的操作步驟

    這篇文章主要介紹了IDEA 打開java文件對應(yīng)的class路徑的操作步驟,本文分步驟給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Java Web會話技術(shù)Session的簡單使用

    Java Web會話技術(shù)Session的簡單使用

    在請求需要傳遞的信息比較多,使用Cookie技術(shù)就會增大請求的難度。而Session可以存儲對象、數(shù)組等信息,并且Session是存儲到服務(wù)器端的,在客戶端請求時只需要將session id一并攜帶給服務(wù)器端。本文將簡單的介紹如何使用Session
    2021-05-05
  • 一篇文章詳解JAVA中的@Schema注解

    一篇文章詳解JAVA中的@Schema注解

    @Schema注解用于描述數(shù)據(jù)模型,包括類和屬性,使得描述更加的詳細和清楚,通常和swagger3一起使用,這篇文章主要介紹了JAVA中@Schema注解的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-04-04
  • Spring Boot系列教程之日志配置

    Spring Boot系列教程之日志配置

    這篇文章主要給大家介紹了關(guān)于Spring Boot系列教程之日志配置的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • Java多線程基礎(chǔ)

    Java多線程基礎(chǔ)

    這篇文章主要介紹Java多線程基礎(chǔ),線程是進程的一個實體,是CPU調(diào)度和分派的基本單位,它是比進程更小的能獨立運行的基本單位,多線程指在單個程序中可以同時運行多個不同的線程執(zhí)行不同的任務(wù),下面來學(xué)習(xí)具體的詳細內(nèi)容
    2021-10-10

最新評論