Spring 实现文件加密上传和下载

发布于:2024-12-18 ⋅ 阅读:(83) ⋅ 点赞:(0)

说明

当前介绍如何在Spring Boot应用程序中实现文件加密上传和下载。主要步骤包括配置文件上传、创建文件上传和下载控制器、实现AES加密和解密工具类以及配置文件存储目录。你可以根据需要调整加密算法和存储策略。

明细

在Spring Boot应用程序中实现文件加密上传和下载涉及几个步骤,包括文件上传、文件加密、文件存储、文件解密以及文件下载。下面是一个详细的实现指南,使用AES加密算法作为示例。

1. 添加依赖

首先,在你的 pom.xml 文件中添加必要的依赖项:

xml

<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Apache Commons IO for file operations -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.11.0</version>
    </dependency>
</dependencies>

2. 配置文件上传

在 application.properties 或 application.yml 文件中配置文件上传的设置:

properties

# application.properties
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

或者

yaml

# application.yml
spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

3. 创建文件上传控制器

创建一个控制器来处理文件上传请求:

java

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@RestController
@RequestMapping("/api/files")
public class FileUploadController {

    @Value("${file.upload-dir}")
    private String uploadDir;

    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            // Save the uploaded file to a temporary location
            Path tempFile = Files.createTempFile(uploadDir, file.getOriginalFilename());
            file.transferTo(tempFile.toFile());

            // Encrypt the file
            File encryptedFile = encryptFile(tempFile.toFile());

            // Delete the temporary file
            Files.deleteIfExists(tempFile);

            return ResponseEntity.ok("File uploaded and encrypted successfully: " + encryptedFile.getName());
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to upload file.");
        }
    }

    private File encryptFile(File file) throws IOException {
        // Implement your encryption logic here
        // For demonstration, we'll use a simple AES encryption
        byte[] encryptedBytes = AESEncryption.encrypt(file);
        File encryptedFile = new File(uploadDir + "/" + file.getName() + ".enc");
        Files.write(encryptedFile.toPath(), encryptedBytes);
        return encryptedFile;
    }
}

4. 创建文件下载控制器

创建一个控制器来处理文件下载请求:

java

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.IOException;

@RestController
@RequestMapping("/api/files")
public class FileDownloadController {

    @Value("${file.upload-dir}")
    private String uploadDir;

    @GetMapping("/download/{filename:.+}")
    public ResponseEntity<Resource> downloadFile(@PathVariable String filename) {
        try {
            // Locate the encrypted file
            File encryptedFile = new File(uploadDir + "/" + filename);
            if (!encryptedFile.exists()) {
                return ResponseEntity.notFound().build();
            }

            // Decrypt the file
            File decryptedFile = decryptFile(encryptedFile);

            // Prepare the response
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + decryptedFile.getName() + "\"");

            Resource resource = new FileSystemResource(decryptedFile);

            // Clean up the decrypted file after sending
            decryptedFile.deleteOnExit();

            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(decryptedFile.length())
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(resource);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body(null);
        }
    }

    private File decryptFile(File file) throws IOException {
        // Implement your decryption logic here
        // For demonstration, we'll use a simple AES decryption
        byte[] decryptedBytes = AESEncryption.decrypt(file);
        File decryptedFile = File.createTempFile("decrypted_", "");
        Files.write(decryptedFile.toPath(), decryptedBytes);
        return decryptedFile;
    }
}

5. 实现AES加密和解密

创建一个工具类来处理AES加密和解密:

java

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.Key;
import java.util.Base64;

public class AESEncryption {

    private static final String ALGORITHM = "AES";
    private static final String KEY = "MySuperSecretKey"; // 16 bytes key

    public static byte[] encrypt(File file) throws Exception {
        Key secretKey = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

        FileInputStream inputStream = new FileInputStream(file);
        byte[] inputBytes = new byte[(int) file.length()];
        inputStream.read(inputBytes);

        byte[] outputBytes = cipher.doFinal(inputBytes);

        inputStream.close();
        return outputBytes;
    }

    public static byte[] decrypt(File file) throws Exception {
        Key secretKey = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);

        FileInputStream inputStream = new FileInputStream(file);
        byte[] inputBytes = new byte[(int) file.length()];
        inputStream.read(inputBytes);

        byte[] outputBytes = cipher.doFinal(inputBytes);

        inputStream.close();
        return outputBytes;
    }
}

6. 配置文件存储目录

在 application.properties 或 application.yml 文件中配置文件存储目录:

properties

# application.properties
file.upload-dir=/path/to/upload/directory

或者

yaml

# application.yml
file:
  upload-dir: /path/to/upload/directory

7. 运行应用程序

确保你的Spring Boot应用程序已经配置好并运行。你可以使用Postman或其他工具来测试文件上传和下载功能。


网站公告

今日签到

点亮在社区的每一天
去签到