自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

強(qiáng)大加密!SpringBoot 實(shí)現(xiàn) RSA+AES 自動(dòng)解密,保障接口安全

開發(fā) 前端
本文展示了如何在 Spring Boot 應(yīng)用中實(shí)現(xiàn) RSA + AES 混合加密方案,從而保障接口數(shù)據(jù)傳輸?shù)陌踩?。通過結(jié)合這兩種加密算法,能夠在確保安全的同時(shí),不影響系統(tǒng)性能。

在當(dāng)今的應(yīng)用開發(fā)中,保障接口的安全性變得尤為關(guān)鍵。尤其是當(dāng)敏感數(shù)據(jù)通過網(wǎng)絡(luò)傳輸時(shí),如何避免數(shù)據(jù)泄露或篡改,成為了開發(fā)者必須考慮的問題。本篇文章將詳細(xì)探討如何在 SpringBoot 3.4 框架下,利用 RSA 和 AES 混合加密方案,確保接口通信的安全性。

為什么需要接口加密?

在沒有加密的情況下,通過網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)很容易被中間人或抓包工具截獲。尤其是當(dāng)數(shù)據(jù)中包含用戶隱私信息或支付數(shù)據(jù)時(shí),缺乏加密的傳輸方式會(huì)帶來巨大的安全隱患。通過對(duì)接口數(shù)據(jù)進(jìn)行加密,即使數(shù)據(jù)在傳輸過程中被截獲,黑客也無法解密和理解數(shù)據(jù)內(nèi)容,從而有效避免了數(shù)據(jù)泄漏的風(fēng)險(xiǎn)。

RSA+AES 混合加密方案的優(yōu)勢(shì)

選擇 RSA 和 AES 混合加密方案,主要是因?yàn)檫@兩種加密算法的結(jié)合,能夠平衡加密的安全性和性能:

  • RSA 是一種非對(duì)稱加密算法,雖然加密安全性高,但加密速度較慢,適合用來加密較小的數(shù)據(jù),比如加密 AES 密鑰。
  • AES 是一種對(duì)稱加密算法,速度較快,適用于大量數(shù)據(jù)的加密,但密鑰的分發(fā)和管理是一個(gè)挑戰(zhàn)。

通過結(jié)合這兩種算法,我們利用 RSA 加密 AES 的密鑰,再使用 AES 加密實(shí)際的數(shù)據(jù),從而實(shí)現(xiàn)了高安全性和高性能的平衡。

實(shí)現(xiàn)原理

  1. 客戶端和服務(wù)端預(yù)先約定好 RSA 公鑰和私鑰。
  2. 客戶端生成一個(gè)隨機(jī)的 AES 密鑰,并使用 RSA 公鑰加密這個(gè) AES 密鑰。
  3. 客戶端使用 AES 密鑰加密實(shí)際的數(shù)據(jù)。
  4. 客戶端將加密后的 AES 密鑰和加密的數(shù)據(jù)一并發(fā)送給服務(wù)端。
  5. 服務(wù)端使用 RSA 私鑰解密得到 AES 密鑰,然后用 AES 密鑰解密數(shù)據(jù)。

項(xiàng)目依賴

在 pom.xml 中,我們需要添加以下依賴,來支持加密解密功能:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.78</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.68</version>
    </dependency>
</dependencies>

加密工具類

接下來,我們將實(shí)現(xiàn)一個(gè)加密工具類,用于處理 RSA 和 AES 加密解密邏輯。以下是該類的實(shí)現(xiàn)代碼:

package com.icoderoad.secureapi.utils;


import org.bouncycastle.jce.provider.BouncyCastleProvider;


import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;


public class EncryptionUtils {


    static {
        Security.addProvider(new BouncyCastleProvider());
    }


    private static final String AES_ALGORITHM = "AES/CBC/PKCS7Padding";
    private static final int AES_KEY_SIZE = 256;
    private static final String RSA_ALGORITHM = "RSA/ECB/PKCS1Padding";
    private static final int RSA_KEY_SIZE = 2048;


    public static KeyPair generateRSAKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(RSA_KEY_SIZE);
        return keyPairGenerator.generateKeyPair();
    }


    public static String keyToString(Key key) {
        return Base64.getEncoder().encodeToString(key.getEncoded());
    }


    public static PublicKey stringToRSAPublicKey(String keyStr) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(keyStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(keySpec);
    }


    public static PrivateKey stringToRSAPrivateKey(String keyStr) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(keyStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }


    public static SecretKey generateAESKey() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(AES_KEY_SIZE);
        return keyGen.generateKey();
    }


    public static SecretKey stringToAESKey(String keyStr) {
        byte[] keyBytes = Base64.getDecoder().decode(keyStr);
        return new SecretKeySpec(keyBytes, "AES");
    }


    public static String encryptWithRSA(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }


    public static String decryptWithRSA(String encryptedData, PrivateKey privateKey) throws Exception {
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }


    public static String encryptWithAES(String data, SecretKey secretKey, byte[] iv) throws Exception {
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM, "BC");
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }


    public static String decryptWithAES(String encryptedData, SecretKey secretKey, byte[] iv) throws Exception {
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM, "BC");
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }


    public static byte[] generateIV() {
        SecureRandom random = new SecureRandom();
        byte[] iv = new byte[16];
        random.nextBytes(iv);
        return iv;
    }
}

請(qǐng)求包裝類與解密攔截器

為了便于加密請(qǐng)求的自動(dòng)解密,我們將創(chuàng)建一個(gè) EncryptedRequest 請(qǐng)求包裝類:

package com.icoderoad.secureapi.model;


import lombok.Data;


@Data
public class EncryptedRequest {
    private String encryptedKey;
    private String iv;
    private String encryptedData;
    private Long timestamp;
    private String signature;
}

接著,創(chuàng)建一個(gè)解密攔截器,自動(dòng)在控制器處理請(qǐng)求前進(jìn)行解密:

package com.icoderoad.secureapi.utils;


import org.bouncycastle.jce.provider.BouncyCastleProvider;


import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;


public class EncryptionUtils {


    static {
        Security.addProvider(new BouncyCastleProvider());
    }


    private static final String AES_ALGORITHM = "AES/CBC/PKCS7Padding";
    private static final int AES_KEY_SIZE = 256;
    private static final String RSA_ALGORITHM = "RSA/ECB/PKCS1Padding";
    private static final int RSA_KEY_SIZE = 2048;


    public static KeyPair generateRSAKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(RSA_KEY_SIZE);
        return keyPairGenerator.generateKeyPair();
    }


    public static String keyToString(Key key) {
        return Base64.getEncoder().encodeToString(key.getEncoded());
    }


    public static PublicKey stringToRSAPublicKey(String keyStr) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(keyStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(keySpec);
    }


    public static PrivateKey stringToRSAPrivateKey(String keyStr) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(keyStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }


    public static SecretKey generateAESKey() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(AES_KEY_SIZE);
        return keyGen.generateKey();
    }


    public static SecretKey stringToAESKey(String keyStr) {
        byte[] keyBytes = Base64.getDecoder().decode(keyStr);
        return new SecretKeySpec(keyBytes, "AES");
    }


    public static String encryptWithRSA(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }


    public static String decryptWithRSA(String encryptedData, PrivateKey privateKey) throws Exception {
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
        Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }


    public static String encryptWithAES(String data, SecretKey secretKey, byte[] iv) throws Exception {
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM, "BC");
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }


    public static String decryptWithAES(String encryptedData, SecretKey secretKey, byte[] iv) throws Exception {
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM, "BC");
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }


    public static byte[] generateIV() {
        SecureRandom random = new SecureRandom();
        byte[] iv = new byte[16];
        random.nextBytes(iv);
        return iv;
    }
}

完整的實(shí)現(xiàn)

  • RSA 密鑰生成在應(yīng)用啟動(dòng)時(shí),生成并存儲(chǔ)公鑰和私鑰。
  • AES 密鑰生成與加密客戶端生成一個(gè)隨機(jī) AES 密鑰,并通過 RSA 公鑰加密。
  • 數(shù)據(jù)加密與解密使用 AES 加密數(shù)據(jù),服務(wù)端使用 RSA 解密 AES 密鑰后,再用 AES 解密數(shù)據(jù)。

總結(jié)

本文展示了如何在 Spring Boot 應(yīng)用中實(shí)現(xiàn) RSA + AES 混合加密方案,從而保障接口數(shù)據(jù)傳輸?shù)陌踩浴Mㄟ^結(jié)合這兩種加密算法,能夠在確保安全的同時(shí),不影響系統(tǒng)性能。

責(zé)任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2023-03-06 08:49:02

加密和解密SpringBoot

2023-09-26 08:25:37

CobaltStri模式Agent

2021-01-07 14:17:31

Springboot數(shù)據(jù)安全加密

2024-07-09 10:13:15

2025-03-26 08:43:17

2015-03-26 11:25:10

對(duì)稱加密加密壓縮加密解密解壓

2024-10-15 10:38:32

2020-12-13 09:40:11

物聯(lián)網(wǎng)物聯(lián)網(wǎng)安全加密方法

2022-06-04 12:25:10

解密加密過濾器

2019-03-19 15:25:47

toplip加密工具開源

2021-03-09 13:18:53

加密解密參數(shù)

2009-09-09 18:50:23

C# 加密RSA

2022-01-26 07:25:09

PythonRSA加解密

2013-11-15 13:06:52

透明加解密hook技術(shù)數(shù)據(jù)安全

2024-04-29 07:50:52

C#AES加密

2024-04-15 10:32:14

2024-08-26 08:34:47

AES加密算法

2024-01-02 10:46:14

2023-12-13 12:27:46

2024-04-22 09:02:06

LicenseC#軟件開發(fā)RSA加密
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)