最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot實(shí)現(xiàn)接口數(shù)據(jù)加解密的三種解決方案

 更新時間:2025年06月10日 09:27:32   作者:Java程序員 擁抱ai  
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)接口數(shù)據(jù)加解密的三種解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

一、為什么需要接口數(shù)據(jù)加解密?

在金融支付、用戶隱私信息傳輸?shù)葓鼍爸?,接口?shù)據(jù)若以明文傳輸,極易被中間人攻擊竊取。例如:

  • 用戶登錄時的密碼、身份證號等敏感信息
  • 企業(yè)間數(shù)據(jù)交互的核心業(yè)務(wù)參數(shù)
  • 移動端與后臺交互的 token 憑證

Spring Boot 提供了多種優(yōu)雅的加解密實(shí)現(xiàn)方案,既能保證數(shù)據(jù)安全,又能最小化業(yè)務(wù)侵入性。本文將從原理到實(shí)戰(zhàn),帶你掌握三種主流實(shí)現(xiàn)方式。

二、核心加解密算法選擇

1. 對稱加密(AES)

優(yōu)勢:加密速度快,適合大流量數(shù)據(jù)傳輸

缺點(diǎn):密鑰需安全存儲,適合客戶端與服務(wù)端一對一場景

// AES 工具類(128位密鑰)
public class AESUtils {
    private static final String KEY = "your_16bit_secret_key";
    private static final String ALGORITHM = "AES/ECB/PKCS5Padding";
    public static String encrypt(String data) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(KEY.getBytes(), "AES"));
        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
    }
    public static String decrypt(String data) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(KEY.getBytes(), "AES"));
        return new String(cipher.doFinal(Base64.getDecoder().decode(data)));
    }
}

2. 非對稱加密(RSA)

優(yōu)勢:密鑰對機(jī)制,適合證書認(rèn)證場景 

缺點(diǎn):加密效率低,通常用于加密對稱密鑰

// RSA 工具類(生成公鑰私鑰對)
public class RSAUtils {
    private static final int KEY_SIZE = 1024;
    private static final String ALGORITHM = "RSA";
    public static Map<String, String> generateKeyPair() throws Exception {
        KeyPairGenerator generator = KeyPairGenerator.getInstance(ALGORITHM);
        generator.initialize(KEY_SIZE);
        KeyPair pair = generator.generateKeyPair();
        return Map.of(
            "publicKey", Base64.getEncoder().encodeToString(pair.getPublic().getEncoded()),
            "privateKey", Base64.getEncoder().encodeToString(pair.getPrivate().getEncoded())
        );
    }
}

三、實(shí)戰(zhàn)方案一:基于 AOP 的透明加解密

1. 核心原理

通過自定義注解標(biāo)記需要加解密的接口,利用 Spring AOP 在方法調(diào)用前后自動處理加解密邏輯,實(shí)現(xiàn)業(yè)務(wù)代碼零侵入。

2. 實(shí)現(xiàn)步驟

(1)定義加解密注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Encrypt {
    // 排除字段(如時間戳等無需加密字段)
    String[] excludeFields() default {};
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Decrypt {
    // 解密失敗是否拋出異常
    boolean throwOnFailure() default true;
}

(2)編寫 AOP 切面

@Aspect
@Component
public class DataEncryptAspect {
    @Around("@annotation(Encrypt)")
    public Object encryptAround(ProceedingJoinPoint joinPoint) throws Throwable {
        // 執(zhí)行原始方法
        Object result = joinPoint.proceed();
        // 對響應(yīng)結(jié)果進(jìn)行AES加密
        return AESUtils.encrypt(JSON.toJSONString(result));
    }
    @Around("@annotation(Decrypt)")
    public Object decryptAround(ProceedingJoinPoint joinPoint) throws Throwable {
        // 獲取請求參數(shù)(假設(shè)參數(shù)為JSON字符串)
        Object[] args = joinPoint.getArgs();
        String encryptedData = (String) args[0];
        // 解密請求參數(shù)
        String decryptedData = AESUtils.decrypt(encryptedData);
        // 替換原始參數(shù)為解密后的數(shù)據(jù)
        args[0] = decryptedData;
        return joinPoint.proceed(args);
    }
}

(3)控制器使用示例

@RestController
@RequestMapping("/api")
public class UserController {
    @PostMapping("/register")
    @Decrypt
    public UserRegisterResponse register(@RequestBody String encryptedData) {
        // 處理解密后的明文數(shù)據(jù)
        UserRegisterRequest request = JSON.parseObject(encryptedData, UserRegisterRequest.class);
        // 業(yè)務(wù)邏輯...
        return new UserRegisterResponse("注冊成功", request.getUserId());
    }
    @GetMapping("/profile")
    @Encrypt
    public UserProfile getProfile(@RequestParam String userId) {
        // 業(yè)務(wù)邏輯獲取用戶信息
        return new UserProfile("張三", "138****1234");
    }
}

3. 方案優(yōu)勢

  • 低侵入性:僅需在接口方法添加注解
  • 靈活配置:可自定義排除字段和異常處理策略
  • 適用場景:適合對單個接口細(xì)粒度控制的場景

四、實(shí)戰(zhàn)方案二:全局過濾器實(shí)現(xiàn)請求響應(yīng)加解密

1. 核心原理

通過實(shí)現(xiàn) FilterHandlerInterceptor,在請求進(jìn)入控制器前解密參數(shù),響應(yīng)離開前加密結(jié)果,實(shí)現(xiàn)全局統(tǒng)一加解密。

2. 實(shí)現(xiàn)步驟

(1)自定義加解密過濾器

@Component
public class DataEncryptFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        // 處理請求解密(假設(shè)請求體為加密的JSON)
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String encryptedBody = IOUtils.toString(httpRequest.getInputStream(), StandardCharsets.UTF_8);
        String decryptedBody = AESUtils.decrypt(encryptedBody);

        // 包裝請求體為可重復(fù)讀取的流
        HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(httpRequest, decryptedBody);

        // 處理響應(yīng)加密
        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper((HttpServletResponse) response, buffer);

        chain.doFilter(requestWrapper, responseWrapper);

        // 對響應(yīng)結(jié)果加密并寫出
        String encryptedResult = AESUtils.encrypt(buffer.toString());
        response.getWriter().write(encryptedResult);
    }
}
// 請求包裝類(重寫getInputStream)
class HttpServletRequestWrapper extends HttpServletRequestWrapper {
    private final String body;
    public HttpServletRequestWrapper(HttpServletRequest request, String body) {
        super(request);
        this.body = body;
    }
    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bis = new ByteArrayInputStream(body.getBytes());
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return bis.read();
            }
            // 省略其他抽象方法實(shí)現(xiàn)
        };
    }
}

(2)配置過濾器生效

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<DataEncryptFilter> encryptFilterRegistration() {
        FilterRegistrationBean<DataEncryptFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new DataEncryptFilter());
        registration.addUrlPatterns("/api/v1/**"); // 配置需要加解密的接口路徑
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE); // 保證過濾器優(yōu)先執(zhí)行
        return registration;
    }
}

3. 方案優(yōu)勢

  • 全局統(tǒng)一:一次配置,所有接口自動加解密
  • 高性能:基于流處理,避免反射帶來的性能損耗
  • 適用場景:適合前后端分離項(xiàng)目的全局?jǐn)?shù)據(jù)加密

五、實(shí)戰(zhàn)方案三:自定義 MessageConverter 實(shí)現(xiàn)透明加解密

1. 核心原理

重寫 Spring MVC 的 HttpMessageConverter,在請求參數(shù)解析和響應(yīng)數(shù)據(jù)序列化階段自動完成加解密,與框架深度整合。

2. 實(shí)現(xiàn)步驟

(1)自定義加解密轉(zhuǎn)換器

public class EncryptingHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
    @Override
    protected boolean supports(Class<?> clazz) {
        return true; // 支持所有類型
    }
    @Override
    protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) 
            throws IOException, HttpMessageNotReadableException {
        // 讀取加密的請求體并解密
        String encrypted = IOUtils.toString(inputMessage.getBody(), StandardCharsets.UTF_8);
        String decrypted = AESUtils.decrypt(encrypted);
        return JSON.parseObject(decrypted, clazz);
    }
    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage) 
            throws IOException, HttpMessageNotWritableException {
        // 將響應(yīng)對象加密后寫出
        String plain = JSON.toJSONString(object);
        String encrypted = AESUtils.encrypt(plain);
        outputMessage.getBody().write(encrypted.getBytes(StandardCharsets.UTF_8));
    }
}

(2)注冊自定義轉(zhuǎn)換器

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new EncryptingHttpMessageConverter());
        // 保留默認(rèn)轉(zhuǎn)換器(可選)
        // converters.addAll(Collections.singletonList(new MappingJackson2HttpMessageConverter()));
    }
}

3. 方案優(yōu)勢

  • 框架級整合:與 Spring MVC 數(shù)據(jù)綁定機(jī)制深度融合
  • 類型安全:自動處理對象與加密字符串的轉(zhuǎn)換
  • 適用場景:適合對請求 / 響應(yīng)格式有嚴(yán)格控制的場景

六、三種方案對比與選型建議

方案一:AOP 注解

  • 侵入性:低
  • 性能:中
  • 靈活性:接口級控制
  • 適用場景:部分接口需要加解密
  • 方案二:全局過濾器
  • 侵入性:中
  • 性能:高
  • 靈活性:路徑級控制
  • 適用場景:前后端分離項(xiàng)目全局加密

方案三:MessageConverter

  • 侵入性:高
  • 性能:最高
  • 靈活性:框架級控制
  • 適用場景:統(tǒng)一請求響應(yīng)格式場景

七、生產(chǎn)環(huán)境最佳實(shí)踐

1. 密鑰管理方案

  • 禁止硬編碼:通過 Spring Config 或配置中心(如 Nacos)管理密鑰
  • 密鑰輪換:定期生成新密鑰,舊密鑰逐步淘汰
  • 硬件安全:敏感系統(tǒng)使用 HSM(硬件安全模塊)存儲密鑰

2. 異常處理機(jī)制

@RestControllerAdvice
public class EncryptExceptionHandler {
    @ExceptionHandler(DecryptionException.class)
    public ResponseEntity<String> handleDecryptionError(DecryptionException e) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                .body("數(shù)據(jù)解密失?。? + e.getMessage());
    }
}

3. 性能優(yōu)化技巧

  • 壓縮后加密:對大體積數(shù)據(jù)先壓縮再加密(Gzip 壓縮可減少 50% 數(shù)據(jù)量)
  • 異步加解密:使用 CompletableFuture 實(shí)現(xiàn)加解密與業(yè)務(wù)邏輯并行處理
  • 緩存加密結(jié)果:對高頻訪問接口的加密結(jié)果進(jìn)行緩存

八、總結(jié)

Spring Boot 提供了從接口級到框架級的完整加解密解決方案,核心是根據(jù)業(yè)務(wù)場景選擇合適的實(shí)現(xiàn)方式:

  • 追求靈活性選 AOP 注解
  • 追求統(tǒng)一性選 全局過濾器
  • 追求框架整合選 MessageConverter

無論哪種方案,都需注意密鑰安全和異常處理。通過本文的源碼示例,開發(fā)者可快速在項(xiàng)目中落地接口數(shù)據(jù)加解密功能,在保障數(shù)據(jù)安全的同時,最小化對現(xiàn)有業(yè)務(wù)的影響。

在數(shù)據(jù)安全日益重要的今天,掌握接口加解密技術(shù),不僅是程序員的核心競爭力,更是保障系統(tǒng)安全的必備技能。選擇合適的方案,讓數(shù)據(jù)在網(wǎng)絡(luò)傳輸中穿上 “防彈衣”,這才是現(xiàn)代后端開發(fā)的正確姿勢。

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 講解Java編程中finally語句的基本使用方法

    講解Java編程中finally語句的基本使用方法

    這篇文章主要介紹了講解Java編程中finally語句的基本使用方法,finally在異常處理中的使用時Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • Java面試問題知識點(diǎn)總結(jié)

    Java面試問題知識點(diǎn)總結(jié)

    本文主要介紹并且整理了Java面試知識點(diǎn)總結(jié),,有需要的小伙伴可以參考下
    2017-04-04
  • 在SpringBoot+MyBatis項(xiàng)目中實(shí)現(xiàn)MySQL讀寫分離的實(shí)戰(zhàn)指南

    在SpringBoot+MyBatis項(xiàng)目中實(shí)現(xiàn)MySQL讀寫分離的實(shí)戰(zhàn)指南

    在Spring Boot和MyBatis項(xiàng)目中實(shí)現(xiàn)MySQL讀寫分離,主要有兩種思路:一種是在應(yīng)用層通過代碼和配置手動控制,另一種是借助中間件自動路由,本文介紹了幾種主流的實(shí)現(xiàn)方案,需要的朋友可以參考下
    2025-11-11
  • MybatisPlus只取一條記錄的兩種方法實(shí)現(xiàn)

    MybatisPlus只取一條記錄的兩種方法實(shí)現(xiàn)

    本文介紹了MyBatis-Plus2.x和3.x版本在IService接口獲取單條記錄的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-07-07
  • 如何使用CountDownLatch同步j(luò)ava多線程

    如何使用CountDownLatch同步j(luò)ava多線程

    這篇文章主要介紹了如何使用CountDownLatch同步j(luò)ava多線程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08
  • Java長字符串加密的實(shí)現(xiàn)

    Java長字符串加密的實(shí)現(xiàn)

    在Java中,字符串是一種常見的數(shù)據(jù)類型,我們經(jīng)常需要對其進(jìn)行加密和解密,本文主要介紹了Java長字符串加密的實(shí)現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • java使用jaxb操作xml示例

    java使用jaxb操作xml示例

    JAXB主要用來實(shí)現(xiàn)對象和XML之間的序列化和反序列化,關(guān)于JAXB的介紹就不多說了,這里主要總結(jié)下基本使用方法和一些注意事項(xiàng)
    2014-04-04
  • JAVA 內(nèi)部類詳解及實(shí)例

    JAVA 內(nèi)部類詳解及實(shí)例

    這篇文章主要介紹了JAVA 內(nèi)部類詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • SpringBoot添加SSL證書的方法

    SpringBoot添加SSL證書的方法

    HTTPS 實(shí)際上就是 HTTP + SSL,使我們的網(wǎng)站更加安全,地址欄上會有一把小鎖。那么如何在SpringBoot添加SSL證書,下面就一起來了解一下
    2021-05-05
  • MyBatis分頁插件PageHelper的使用與原理

    MyBatis分頁插件PageHelper的使用與原理

    提到插件相信大家都知道,插件的存在主要是用來改變或者增強(qiáng)原有的功能,MyBatis中也一樣,下面這篇文章主要給大家介紹了關(guān)于Mybatis第三方PageHelper分頁插件的使用與原理,需要的朋友可以參考下
    2023-02-02

最新評論

开原市| 永州市| 百色市| 当涂县| 双流县| 柞水县| 兖州市| 开远市| 改则县| 来安县| 项城市| 徐闻县| 岑溪市| 靖西县| 桂东县| 泗水县| 东乌珠穆沁旗| 宿州市| 宝应县| 监利县| 大邑县| 寿宁县| 淮滨县| 东乌珠穆沁旗| 苗栗县| 环江| 苗栗市| 望城县| 涞源县| 图木舒克市| 两当县| 高邮市| 驻马店市| 巩义市| 彰化市| 葫芦岛市| 宜兰市| 南雄市| 察雅县| 梅河口市| 大渡口区|