개발노트/Java

[Java] zip4j 로 파일 암호화/복호화 스트림 처리

dev-mylee 2025. 1. 24. 14:34

zip4j 라이브러리를 사용해서 파일을 암호화하고 stream으로 처리하는 방법 정리해봄!

 

0. 개발 환경

  • Java 17
  • Spring Boot
  • zip4j 2.11.5

 

1. 라이브러리 의존성 추가 (Maven pom.xml)

<dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>2.11.5</version>
</dependency>

 

 

 

2. 파일 업로드 (암호화)

zipParameters.setFileNameInZip(zip파일 내부에 저장될 원본파일명) 꼭 지정해줘야함!!

public void encryptAndSaveFile(MultipartFile file, String storePath, String password) throws Exception {
    // 저장 경로 생성
    File saveFolder = new File(storePath);
    if (!saveFolder.exists()) {
        saveFolder.mkdirs();
    }
    
    String zipFileName = "encrypted_" + file.getOriginalFilename() + ".zip";
    String zipFilePath = storePath + File.separator + zipFileName;
    File zipFile = new File(zipFilePath);
    
    // ZIP 파일 설정
    ZipParameters zipParameters = new ZipParameters();
    zipParameters.setEncryptFiles(true);
    zipParameters.setEncryptionMethod(EncryptionMethod.AES);
    zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
    zipParameters.setFileNameInZip(file.getOriginalFilename());
    
    // ZIP 파일 생성 및 암호화
    try (FileOutputStream fos = new FileOutputStream(zipFile);
         ZipFile zf = new ZipFile(zipFile, password.toCharArray())) {
        zf.addStream(file.getInputStream(), zipParameters);
    }
}

 

 

 

 

3. 파일 다운로드 (복호화)

- response.setContentType / response.setHeader 설정 안 했더니 다운로드 X

(원본파일(.txt)의 내용이 브라우저창에서 열려버림)

- File 객체 생성해서 getAbsolutePath 받아와야 정상적으로 다운로드 가능!

public void downloadDecryptedFile(String zipPath, String fileName, String password, HttpServletResponse response) throws Exception {
    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
    
    File zFile = new File(zipPath, fileName);
    String fullPath = zFile.getAbsolutePath();
    
    try (ZipFile zipFile = new ZipFile(zipPath, password.toCharArray());
         InputStream zipInputStream = zipFile.getInputStream(zipFile.getFileHeader(fileName));
         OutputStream outputStream = response.getOutputStream()) {
            
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = zipInputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.flush();
    }
}

 

 

 

 

4. 주요 포인트 정리

  1. 물리적 파일 저장을 위한 FileOutputStream 사용
  2. 저장 경로 사전 생성 체크
  3. ZipParameters에 fileNameInZip 설정 필수 (안하면 오류 발생)
  4. AES-256 암호화 적용
  5. try-with-resources로 스트림 자동 close
  6. 버퍼 사용해서 메모리 효율적으로 관리
  7. 다운로드 시 원본 파일명으로 제공

실무에서 전자문서 암호화 저장 기능을 개발하면서 zip4j를 처음 써봤는데, 생각보다 직관적이고 사용하기 편했다.

특히 암호화된 zip 파일을 만들고 다운로드할 때 스트림으로 처리할 수 있어서 좋았다.

 

참고사항

  • zip4j 공식 문서: https://github.com/srikanth-lingala/zip4j
  • AES-256 암호화가 기본 지원돼서 별도 설정 필요 없음
  • 파일명에 한글 사용해도 인코딩 문제 없음
  • Spring의 MultipartFile과 함께 사용하기 좋음

'개발노트 > Java' 카테고리의 다른 글

[Java] StringUtil.nvlStr() 사용법 정리  (0) 2025.01.11