说明
当前介绍如何在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或其他工具来测试文件上传和下载功能。