在Spring Boot中实现加密Zip压缩与解密下载

142 阅读2分钟

在Spring Boot中实现加密Zip压缩与解密下载

1. 应用场景

在文件传输场景中,常需要对敏感数据进行加密压缩,确保只有授权用户能解压查看。本文通过Spring Boot整合zip4j库,实现以下功能:

  1. 将多个文件加密压缩为受密码保护的Zip文件
  2. 通过接口下载加密Zip文件
  3. 提供密码验证和解密下载单个文件的能力

2. 环境准备

2.1 添加依赖

<!-- pom.xml -->
<dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>2.11.5</version>
</dependency>

2.2 配置文件参数

# application.yml
zip:
  password: securePassword123! # 生产环境建议使用加密配置
  temp-dir: /tmp/files

3. 实现加密压缩

3.1 创建加密Zip服务类

@Service
public class ZipService {
    
    @Value("${zip.password}")
    private String zipPassword;
    
    @Value("${zip.temp-dir}")
    private String tempDir;

    public File createEncryptedZip(List<File> filesToZip) throws IOException {
        String zipName = "encrypted_" + System.currentTimeMillis() + ".zip";
        File zipFile = new File(tempDir, zipName);
        
        ZipParameters zipParameters = new ZipParameters();
        zipParameters.setEncryptFiles(true);
        zipParameters.setEncryptionMethod(EncryptionMethod.AES);
        zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
        
        try(ZipOutputStream zos = new ZipOutputStream(zipFile, zipPassword.toCharArray())) {
            for (File file : filesToZip) {
                zipParameters.setFileNameInZip(file.getName());
                zos.putNextEntry(zipParameters);
                Files.copy(file.toPath(), zos);
                zos.closeEntry();
            }
        }
        return zipFile;
    }
}

3.2 文件下载接口

@RestController
@RequestMapping("/api/zip")
public class ZipController {

    @Autowired
    private ZipService zipService;

    @PostMapping("/encrypt")
    public ResponseEntity<Resource> encryptAndDownload(@RequestBody List<MultipartFile> files) 
        throws IOException {
        
        List<File> tempFiles = files.stream()
            .map(this::saveToTemp)
            .collect(Collectors.toList());
        
        File zipFile = zipService.createEncryptedZip(tempFiles);
        
        return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + zipFile.getName())
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(new FileSystemResource(zipFile));
    }

    private File saveToTemp(MultipartFile file) {
        // 实现文件暂存逻辑
    }
}

4. 实现解密下载

4.1 解密服务方法

public File extractFile(File zipFile, String password, String targetFileName) 
    throws IOException {
    
    try {
        ZipFile zip = new ZipFile(zipFile);
        if (!zip.isValidZipPassword(password.toCharArray())) {
            throw new RuntimeException("Invalid password");
        }
        
        File outputFile = new File(tempDir, targetFileName);
        zip.extractFile(targetFileName, outputFile, password.toCharArray());
        return outputFile;
    } catch (net.lingala.zip4j.exception.ZipException e) {
        throw new RuntimeException("解密失败: " + e.getMessage());
    }
}

4.2 解密下载接口

@GetMapping("/decrypt")
public ResponseEntity<Resource> decryptFile(
    @RequestParam String zipFileName,
    @RequestParam String password,
    @RequestParam String targetFile) throws IOException {

    File zipFile = new File(tempDir, zipFileName);
    File decryptedFile = zipService.extractFile(zipFile, password, targetFile);
    
    return ResponseEntity.ok()
        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + decryptedFile.getName())
        .body(new FileSystemResource(decryptedFile));
}

5. 安全增强建议

  1. 密码管理:避免硬编码密码,推荐使用Spring Cloud Config或Vault管理密钥
  2. 临时文件清理:添加定时任务定期清理临时目录
  3. 传输安全:务必启用HTTPS防止中间人攻击
  4. 访问控制:添加权限验证注解(如@PreAuthorize)
  5. 防暴力破解:对解密接口添加限流机制

6. 异常处理

全局异常处理示例:

@ControllerAdvice
public class ZipExceptionHandler {

    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> handleZipErrors(RuntimeException ex) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
            .body("处理失败: " + ex.getMessage());
    }
}

7. 测试流程

  1. 使用Postman上传文件到/api/zip/encrypt
  2. 下载加密Zip文件,验证需要密码才能打开
  3. 调用解密接口验证密码正确性并下载单个文件

8. 总结

本文实现了以下核心功能:

  • 基于AES-256的Zip加密压缩
  • 安全的文件下载流处理
  • 密码验证与文件提取功能

注意事项

  1. 大文件处理建议使用分块传输
  2. 生产环境需要添加日志监控
  3. 建议对压缩操作添加异步处理
  4. 前端需要配合处理大文件上传/下载进度

可根据具体需求扩展文件列表管理、密码单独存储等功能。