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. 주요 포인트 정리
- 물리적 파일 저장을 위한 FileOutputStream 사용
- 저장 경로 사전 생성 체크
- ZipParameters에 fileNameInZip 설정 필수 (안하면 오류 발생)
- AES-256 암호화 적용
- try-with-resources로 스트림 자동 close
- 버퍼 사용해서 메모리 효율적으로 관리
- 다운로드 시 원본 파일명으로 제공
실무에서 전자문서 암호화 저장 기능을 개발하면서 zip4j를 처음 써봤는데, 생각보다 직관적이고 사용하기 편했다.
특히 암호화된 zip 파일을 만들고 다운로드할 때 스트림으로 처리할 수 있어서 좋았다.
참고사항
- zip4j 공식 문서: https://github.com/srikanth-lingala/zip4j
- AES-256 암호화가 기본 지원돼서 별도 설정 필요 없음
- 파일명에 한글 사용해도 인코딩 문제 없음
- Spring의 MultipartFile과 함께 사용하기 좋음
'개발노트 > Java' 카테고리의 다른 글
[Java] StringUtil.nvlStr() 사용법 정리 (0) | 2025.01.11 |
---|