Spring Boot中实现数据加密和解密处理

星空下的诗人 2023-03-13 ⋅ 20 阅读

数据加密和解密是在应用程序中保护敏感数据安全的重要步骤。Spring Boot提供了各种方式来实现数据加密和解密,以确保数据在存储和传输过程中的安全性。本文将介绍如何在Spring Boot中实现数据加密和解密处理。

1. 对称加密算法

对称加密算法使用同一个密钥来进行数据加密和解密。在Spring Boot中,可以使用Java Cryptography Architecture (JCA)提供的各种对称加密算法,如AES(Advanced Encryption Standard)来实现数据加密和解密。

1.1 添加依赖

首先,在你的Spring Boot项目的pom.xml文件中添加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>javax.crypto</groupId>
    <artifactId>javax.crypto-api</artifactId>
</dependency>

1.2 创建加密和解密工具类

接下来,创建一个加密和解密工具类EncryptionUtils,用于封装加密和解密的逻辑。

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class EncryptionUtils {
    private static final String ALGORITHM = "AES";
    private static final String KEY = "YourSecretKey";

    public static String encrypt(String data) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(StandardCharsets.UTF_8), ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    public static String decrypt(String encryptedData) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(StandardCharsets.UTF_8), ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        byte[] decryptedData = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
        return new String(decryptedData, StandardCharsets.UTF_8);
    }
}

1.3 在Spring Boot中使用加密和解密工具类

现在,你可以在Spring Boot的任何地方使用这个工具类来加密和解密数据。例如,你可以在控制器中使用:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
    @GetMapping("/encrypt/{data}")
    public String encrypt(@PathVariable String data) throws Exception {
        return EncryptionUtils.encrypt(data);
    }

    @GetMapping("/decrypt/{encryptedData}")
    public String decrypt(@PathVariable String encryptedData) throws Exception {
        return EncryptionUtils.decrypt(encryptedData);
    }
}

这样,当你访问/encrypt/{data}时,data将被加密并返回加密后的结果;当你访问/decrypt/{encryptedData}时,encryptedData将被解密并返回解密后的结果。

2. 非对称加密算法

非对称加密算法使用一对密钥,分别称为公钥和私钥,进行数据加密和解密。在Spring Boot中,可以使用Java Cryptography Architecture (JCA)提供的非对称加密算法,如RSA(Rivets-Shamir-Adleman)来实现数据加密和解密。

2.1 添加依赖

首先,在你的Spring Boot项目的pom.xml文件中添加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2.2 创建加密和解密工具类

接下来,创建一个加密和解密工具类EncryptionUtils,用于封装加密和解密的逻辑。

import org.springframework.core.io.ClassPathResource;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.security.crypto.codec.Utf8;
import org.springframework.util.FileCopyUtils;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;

public class EncryptionUtils {
    private static final String KEY_STORE_LOCATION = "keystore.jks";
    private static final String KEY_STORE_PASSWORD = "YourKeyStorePassword";
    private static final String KEY_PASSWORD = "YourKeyPassword";
    private static final String ALGORITHM = "RSA";

    public static String encrypt(String data) throws Exception {
        byte[] publicKeyBytes = readKeyFile("public.key");
        PublicKey publicKey = RSAUtils.getPublicKey(publicKeyBytes);

        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return new String(Base64.encode(encryptedData));
    }

    public static String decrypt(String encryptedData) throws Exception {
        byte[] privateKeyBytes = readKeyFile("private.key");
        PrivateKey privateKey = RSAUtils.getPrivateKey(privateKeyBytes);

        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        byte[] decryptedData = cipher.doFinal(Base64.decode(encryptedData.getBytes()));
        return new String(Utf8.decode(decryptedData));
    }

    public static String sign(String data) throws Exception {
        byte[] privateKeyBytes = readKeyFile("private.key");
        PrivateKey privateKey = RSAUtils.getPrivateKey(privateKeyBytes);

        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(data.getBytes(StandardCharsets.UTF_8));

        byte[] signedData = signature.sign();
        return new String(Base64.encode(signedData));
    }

    public static boolean verify(String data, String signatureData) throws Exception {
        byte[] publicKeyBytes = readKeyFile("public.key");
        PublicKey publicKey = RSAUtils.getPublicKey(publicKeyBytes);

        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(publicKey);
        signature.update(data.getBytes(StandardCharsets.UTF_8));

        return signature.verify(Base64.decode(signatureData.getBytes()));
    }

    private static byte[] readKeyFile(String fileName) throws Exception {
        ClassPathResource resource = new ClassPathResource(fileName);
        return FileCopyUtils.copyToByteArray(resource.getInputStream());
    }
}

2.3 生成公钥和私钥

在使用非对称加密算法之前,需要先生成公钥和私钥对。可以使用以下命令来生成:

# 生成私钥
keytool -genkeypair -alias mykey -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.jks -storepass YourKeyStorePassword -keypass YourKeyPassword

# 导出公钥
keytool -exportcert -alias mykey -file public.cer -keystore keystore.jks -storepass YourKeyStorePassword

# 导出私钥
keytool -importkeystore -srckeystore keystore.jks -srcalias mykey -destkeystore private.p12 -deststoretype PKCS12 -deststorepass YourKeyStorePassword -destkeypass YourKeyPassword

将生成的public.cer文件重命名为public.key,将private.p12文件重命名为private.key,并将它们放在resources目录下。

2.4 在Spring Boot中使用加密和解密工具类

现在,你可以在Spring Boot的任何地方使用这个工具类来加密和解密数据。例如,你可以在控制器中使用:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
    @GetMapping("/encrypt/{data}")
    public String encrypt(@PathVariable String data) throws Exception {
        return EncryptionUtils.encrypt(data);
    }

    @GetMapping("/decrypt/{encryptedData}")
    public String decrypt(@PathVariable String encryptedData) throws Exception {
        return EncryptionUtils.decrypt(encryptedData);
    }

    @GetMapping("/sign/{data}")
    public String sign(@PathVariable String data) throws Exception {
        return EncryptionUtils.sign(data);
    }

    @GetMapping("/verify/{data}/{signatureData}")
    public boolean verify(@PathVariable String data, @PathVariable String signatureData) throws Exception {
        return EncryptionUtils.verify(data, signatureData);
    }
}

这样,当你访问/encrypt/{data}时,data将被加密并返回加密后的结果;当你访问/decrypt/{encryptedData}时,encryptedData将被解密并返回解密后的结果。同样,当你访问/sign/{data}时,data将被数字签名并返回签名后的结果;当你访问/verify/{data}/{signatureData}时,将验证数据的数字签名是否有效,并返回验证结果。

总结

本文介绍了如何在Spring Boot中实现数据加密和解密处理。通过使用对称和非对称加密算法,可以在应用程序中保护敏感数据的安全性。无论是对称加密还是非对称加密,都需要使用安全的密钥和适当的加密算法来确保数据的保密性和完整性。希望本文对你在Spring Boot中实现数据加密和解密处理有所帮助!


全部评论: 0

    我有话说: