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

利用SpringBoot實(shí)現(xiàn)RSA+AES混合加密

 更新時(shí)間:2026年01月28日 09:09:08   作者:我愛(ài)娃哈哈  
用戶注冊(cè)時(shí),密碼明文傳輸被攔截?支付信息在傳輸過(guò)程中被竊取?或者敏感數(shù)據(jù)在接口調(diào)用時(shí)被中間人攻擊?再或者App被反編譯,接口參數(shù)被破解?今天我們就來(lái)聊聊如何用SpringBoot實(shí)現(xiàn)RSA+AES混合加密,讓你的接口數(shù)據(jù)傳輸更安全,需要的朋友可以參考下

引言:接口數(shù)據(jù)安全的重要性

用戶注冊(cè)時(shí),密碼明文傳輸被攔截?支付信息在傳輸過(guò)程中被竊???或者敏感數(shù)據(jù)在接口調(diào)用時(shí)被中間人攻擊?再或者App被反編譯,接口參數(shù)被破解?

這就是接口數(shù)據(jù)安全的經(jīng)典難題。傳統(tǒng)的明文傳輸方式已經(jīng)無(wú)法滿足現(xiàn)代應(yīng)用的安全需求。今天我們就來(lái)聊聊如何用SpringBoot實(shí)現(xiàn)RSA+AES混合加密,讓你的接口數(shù)據(jù)傳輸更安全。

為什么需要接口加密?

先說(shuō)說(shuō)為什么需要接口加密。

想象一下,你是一家金融公司的后端工程師。用戶在App上進(jìn)行轉(zhuǎn)賬操作,傳輸?shù)你y行卡號(hào)、轉(zhuǎn)賬金額、支付密碼等敏感信息如果明文傳輸,一旦被攔截,后果不堪設(shè)想。

接口加密的必要性:

  • 數(shù)據(jù)安全:防止敏感信息泄露
  • 身份認(rèn)證:防止接口被惡意調(diào)用
  • 防篡改:確保數(shù)據(jù)傳輸?shù)耐暾?/li>
  • 合規(guī)要求:滿足金融、醫(yī)療等行業(yè)安全規(guī)范

技術(shù)選型:為什么選擇RSA+AES混合加密?

RSA:非對(duì)稱加密,解決密鑰分發(fā)問(wèn)題

RSA是非對(duì)稱加密算法,有公鑰和私鑰:

  • 公鑰加密,私鑰解密:數(shù)據(jù)加密傳輸
  • 私鑰簽名,公鑰驗(yàn)簽:數(shù)據(jù)完整性驗(yàn)證
  • 密鑰分發(fā)安全:公鑰可以公開(kāi),私鑰保密

AES:對(duì)稱加密,解決性能問(wèn)題

AES是對(duì)稱加密算法,加密解密使用同一密鑰:

  • 加密速度快:適合大量數(shù)據(jù)加密
  • 安全性高:256位密鑰安全性足夠
  • 實(shí)現(xiàn)簡(jiǎn)單:算法成熟穩(wěn)定

混合加密的優(yōu)勢(shì)

  • 安全:RSA解決密鑰分發(fā)問(wèn)題
  • 高效:AES解決性能問(wèn)題
  • 靈活:結(jié)合兩種算法優(yōu)勢(shì)

系統(tǒng)架構(gòu)設(shè)計(jì)

我們的加密體系主要包括以下幾個(gè)模塊:

  1. 密鑰管理:RSA公私鑰、AES密鑰管理
  2. 加密流程:數(shù)據(jù)加密處理
  3. 解密流程:數(shù)據(jù)解密處理
  4. 自動(dòng)處理:SpringBoot攔截器自動(dòng)處理
  5. 安全驗(yàn)證:數(shù)據(jù)完整性校驗(yàn)

核心實(shí)現(xiàn)思路

1. 加密工具類

@Component
public class EncryptionUtil {
    
    /**
     * RSA加密AES密鑰
     */
    public static String encryptAesKey(String aesKey, String rsaPublicKey) throws Exception {
        PublicKey publicKey = getPublicKey(rsaPublicKey);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        
        byte[] encrypted = cipher.doFinal(aesKey.getBytes());
        return Base64.getEncoder().encodeToString(encrypted);
    }
    
    /**
     * AES加密數(shù)據(jù)
     */
    public static String encryptData(String data, String aesKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(aesKey.getBytes(), "AES");
        IvParameterSpec iv = new IvParameterSpec("0000000000000000".getBytes()); // 實(shí)際項(xiàng)目中應(yīng)使用隨機(jī)IV
        
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
        byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encrypted);
    }
    
    /**
     * RSA解密AES密鑰
     */
    public static String decryptAesKey(String encryptedAesKey, String rsaPrivateKey) throws Exception {
        PrivateKey privateKey = getPrivateKey(rsaPrivateKey);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        
        byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedAesKey));
        return new String(decrypted);
    }
    
    /**
     * AES解密數(shù)據(jù)
     */
    public static String decryptData(String encryptedData, String aesKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(aesKey.getBytes(), "AES");
        IvParameterSpec iv = new IvParameterSpec("0000000000000000".getBytes());
        
        cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
        byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
        return new String(decrypted, StandardCharsets.UTF_8);
    }
    
    private static PublicKey getPublicKey(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(spec);
    }
    
    private static PrivateKey getPrivateKey(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(spec);
    }
}

2. 加密請(qǐng)求包裝器

public class EncryptedRequestWrapper extends HttpServletRequestWrapper {
    
    private final String body;
    
    public EncryptedRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        body = getBody(request);
    }
    
    private String getBody(HttpServletRequest request) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        try (BufferedReader reader = request.getReader()) {
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
        }
        return stringBuilder.toString();
    }
    
    @Override
    public ServletInputStream getInputStream() throws IOException {
        // 解密請(qǐng)求體
        String decryptedBody = decryptRequestBody(body);
        ByteArrayInputStream byteArrayInputStream = 
            new ByteArrayInputStream(decryptedBody.getBytes(StandardCharsets.UTF_8));
        
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return byteArrayInputStream.available() == 0;
            }
            
            @Override
            public boolean isReady() {
                return true;
            }
            
            @Override
            public void setReadListener(ReadListener readListener) {
                // 不需要實(shí)現(xiàn)
            }
            
            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }
    
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
    
    private String decryptRequestBody(String encryptedBody) {
        try {
            // 假設(shè)請(qǐng)求體格式為: {"encryptedData": "xxx", "encryptedKey": "xxx"}
            JSONObject jsonObject = JSON.parseObject(encryptedBody);
            String encryptedData = jsonObject.getString("encryptedData");
            String encryptedKey = jsonObject.getString("encryptedKey");
            
            // 解密AES密鑰
            String aesKey = EncryptionUtil.decryptAesKey(encryptedKey, getPrivateKey());
            
            // 解密數(shù)據(jù)
            return EncryptionUtil.decryptData(encryptedData, aesKey);
        } catch (Exception e) {
            throw new RuntimeException("解密失敗", e);
        }
    }
    
    private String getPrivateKey() {
        // 從配置或數(shù)據(jù)庫(kù)獲取私鑰
        return System.getProperty("rsa.private.key");
    }
}

3. 解密攔截器

@Component
public class DecryptionInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) throws Exception {
        
        // 檢查是否需要解密
        if (isEncryptedRequest(request)) {
            // 包裝請(qǐng)求,實(shí)現(xiàn)自動(dòng)解密
            EncryptedRequestWrapper wrappedRequest = new EncryptedRequestWrapper(request);
            // 將包裝后的請(qǐng)求傳遞給后續(xù)處理
            RequestContextHolder.getRequestAttributes()
                .setAttribute("wrappedRequest", wrappedRequest, RequestAttributes.SCOPE_REQUEST);
        }
        
        return true;
    }
    
    private boolean isEncryptedRequest(HttpServletRequest request) {
        // 檢查請(qǐng)求頭或參數(shù),判斷是否為加密請(qǐng)求
        String encryptedHeader = request.getHeader("X-Encrypted");
        return "true".equalsIgnoreCase(encryptedHeader);
    }
}

4. 自定義參數(shù)解析器

@Component
public class EncryptedParameterResolver implements HandlerMethodArgumentResolver {
    
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(EncryptedParam.class);
    }
    
    @Override
    public Object resolveArgument(MethodParameter parameter, 
                                ModelAndViewContainer mavContainer,
                                NativeWebRequest webRequest, 
                                WebDataBinderFactory binderFactory) throws Exception {
        
        String encryptedValue = webRequest.getParameter(parameter.getParameterName());
        if (encryptedValue != null) {
            // 解密參數(shù)
            String decryptedValue = decryptParameter(encryptedValue);
            return convertValue(decryptedValue, parameter.getParameterType());
        }
        
        return null;
    }
    
    private String decryptParameter(String encryptedValue) {
        try {
            // 解密邏輯
            return EncryptionUtil.decryptData(encryptedValue, getAesKey());
        } catch (Exception e) {
            throw new RuntimeException("參數(shù)解密失敗", e);
        }
    }
    
    private String getAesKey() {
        // 獲取AES密鑰
        return System.getProperty("aes.key");
    }
    
    private Object convertValue(String value, Class<?> targetType) {
        // 類型轉(zhuǎn)換邏輯
        return value;
    }
}

5. 注解定義

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptedParam {
    String value() default "";
}

6. 控制器使用示例

@RestController
public class UserController {
    
    @PostMapping("/user/register")
    public ResponseEntity<String> register(
            @RequestBody @EncryptedBody UserRegisterRequest request) {
        // 業(yè)務(wù)邏輯
        return ResponseEntity.ok("注冊(cè)成功");
    }
    
    @PostMapping("/user/login")
    public ResponseEntity<String> login(
            @EncryptedParam("username") String username,
            @EncryptedParam("password") String password) {
        // 業(yè)務(wù)邏輯
        return ResponseEntity.ok("登錄成功");
    }
}

高級(jí)特性實(shí)現(xiàn)

1. 密鑰動(dòng)態(tài)管理

@Service
public class KeyManagementService {
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    /**
     * 生成新的AES密鑰
     */
    public String generateAesKey() {
        byte[] key = new byte[32]; // 256位
        new SecureRandom().nextBytes(key);
        return Base64.getEncoder().encodeToString(key);
    }
    
    /**
     * 獲取或創(chuàng)建AES密鑰
     */
    public String getOrCreateAesKey(String userId) {
        String cacheKey = "aes_key:" + userId;
        String cachedKey = redisTemplate.opsForValue().get(cacheKey);
        
        if (cachedKey == null) {
            cachedKey = generateAesKey();
            // 設(shè)置過(guò)期時(shí)間,定期更新密鑰
            redisTemplate.opsForValue().set(cacheKey, cachedKey, Duration.ofHours(24));
        }
        
        return cachedKey;
    }
    
    /**
     * 輪換密鑰
     */
    public void rotateKey(String userId) {
        String newKey = generateAesKey();
        String cacheKey = "aes_key:" + userId;
        redisTemplate.opsForValue().set(cacheKey, newKey, Duration.ofHours(24));
    }
}

2. 請(qǐng)求簽名驗(yàn)證

@Component
public class SignatureValidator {
    
    public boolean validateSignature(String data, String signature, String publicKey) {
        try {
            Signature sign = Signature.getInstance("SHA256withRSA");
            sign.initVerify(EncryptionUtil.getPublicKey(publicKey));
            sign.update(data.getBytes(StandardCharsets.UTF_8));
            return sign.verify(Base64.getDecoder().decode(signature));
        } catch (Exception e) {
            return false;
        }
    }
}

3. 批量數(shù)據(jù)處理

public class BatchEncryptionProcessor {
    
    public List<String> encryptBatchData(List<String> dataList, String aesKey) {
        return dataList.parallelStream()
            .map(data -> {
                try {
                    return EncryptionUtil.encryptData(data, aesKey);
                } catch (Exception e) {
                    throw new RuntimeException("批量加密失敗", e);
                }
            })
            .collect(Collectors.toList());
    }
}

性能優(yōu)化建議

1. 緩存優(yōu)化

@Component
public class EncryptedCacheManager {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    public void cacheEncryptedData(String key, String encryptedData) {
        // 緩存加密后的數(shù)據(jù)
        redisTemplate.opsForValue().set("encrypted:" + key, encryptedData, Duration.ofMinutes(30));
    }
    
    public String getCachedEncryptedData(String key) {
        return (String) redisTemplate.opsForValue().get("encrypted:" + key);
    }
}

2. 線程池優(yōu)化

@Configuration
public class EncryptionThreadPoolConfig {
    
    @Bean("encryptionExecutor")
    public Executor encryptionExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("encryption-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

安全考慮

1. 密鑰安全存儲(chǔ)

@Component
public class SecureKeyStore {
    
    /**
     * 從環(huán)境變量或配置中心獲取密鑰
     */
    public String getPrivateKey() {
        String key = System.getenv("RSA_PRIVATE_KEY");
        if (key == null) {
            // 從配置中心獲取
            key = configService.getRsaPrivateKey();
        }
        return key;
    }
}

2. 傳輸安全

  • 使用HTTPS協(xié)議
  • 定期輪換密鑰
  • 限制密鑰有效期
  • 監(jiān)控異常訪問(wèn)

最佳實(shí)踐

1. 選擇性加密

public class EncryptionPolicy {
    
    public static boolean shouldEncrypt(String fieldName) {
        // 只對(duì)敏感字段進(jìn)行加密
        Set<String> sensitiveFields = Set.of("password", "idCard", "phone", "email");
        return sensitiveFields.contains(fieldName.toLowerCase());
    }
}

2. 錯(cuò)誤處理

@ControllerAdvice
public class EncryptionExceptionHandler {
    
    @ExceptionHandler(EncryptionException.class)
    public ResponseEntity<String> handleEncryptionError(EncryptionException e) {
        log.error("加密解密異常", e);
        return ResponseEntity.status(400).body("數(shù)據(jù)格式錯(cuò)誤");
    }
}

總結(jié)

通過(guò)SpringBoot實(shí)現(xiàn)RSA+AES混合加密,我們可以構(gòu)建一個(gè)安全的接口數(shù)據(jù)傳輸體系。關(guān)鍵在于:

  1. 合理架構(gòu):加密工具、攔截器、參數(shù)解析器的合理設(shè)計(jì)
  2. 性能考慮:AES加密大數(shù)據(jù),RSA加密密鑰
  3. 安全實(shí)踐:密鑰安全存儲(chǔ)、定期輪換
  4. 用戶體驗(yàn):自動(dòng)解密,業(yè)務(wù)代碼無(wú)感知

記住,安全不是一成不變的,需要根據(jù)業(yè)務(wù)特點(diǎn)和安全威脅持續(xù)優(yōu)化。掌握了這些技巧,你就能讓接口數(shù)據(jù)傳輸更加安全可靠。

以上就是利用SpringBoot實(shí)現(xiàn)RSA+AES混合加密的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot RSA+AES混合加密的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

铜鼓县| 沁源县| 永年县| 五家渠市| 新丰县| 镇安县| 石狮市| 达尔| 老河口市| 郎溪县| 永城市| 封开县| 商洛市| 剑河县| 达尔| 平泉县| 丹阳市| 桂阳县| 阳江市| 商城县| 凤阳县| 阳信县| 尤溪县| 金寨县| 鹤峰县| 潮州市| 简阳市| 澎湖县| 射阳县| 夏津县| 宿州市| 新邵县| 常州市| 舒兰市| 金秀| 乌拉特后旗| 高台县| 襄樊市| 葫芦岛市| 临漳县| 丰顺县|