说明
当前介绍如何在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: 10MBmax-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 locationPath tempFile = Files.createTempFile(uploadDir, file.getOriginalFilename());file.transferTo(tempFile.toFile());// Encrypt the fileFile encryptedFile = encryptFile(tempFile.toFile());// Delete the temporary fileFiles.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 encryptionbyte[] 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 fileFile encryptedFile = new File(uploadDir + "/" + filename);if (!encryptedFile.exists()) {return ResponseEntity.notFound().build();}// Decrypt the fileFile decryptedFile = decryptFile(encryptedFile);// Prepare the responseHttpHeaders headers = new HttpHeaders();headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + decryptedFile.getName() + "\"");Resource resource = new FileSystemResource(decryptedFile);// Clean up the decrypted file after sendingdecryptedFile.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 decryptionbyte[] 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 keypublic 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或其他工具来测试文件上传和下载功能。