Shanjana M
Shanjana M

Reputation: 15

Zip a folder with password protection at folder level using Java

I'm trying out an automation which needs to zip a folder and password protect it at folder level. I used zip4j and able to achieve the password protection at file level only.

Here is my code which does the zipping and password protection at file level.


import java.io.File;

import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.EncryptionMethod;

public class ZipWithPasswordExample {
    public static void main(String[] args) {
        // Source folder to be zipped
        String sourceFolderPath = "<source folder>";
        // Destination zip file path
        String destinationZipFilePath = "<destination folder>.zip";
        // Password for encryption
        String password = "<Password>";

        try {
            // Create a new ZipFile object
            ZipFile zipFile = new ZipFile(destinationZipFilePath, password.toCharArray());

            // Parameters for creating the zip file
            ZipParameters parameters = new ZipParameters();
            parameters.setEncryptFiles(true);
            parameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);

            // Add folder to the zip file
            File sourceFolder = new File(sourceFolderPath);
            zipFile.addFolder(sourceFolder, parameters);

            System.out.println("Folder successfully zipped and encrypted!");
        } catch (ZipException e) {
            e.printStackTrace();
        }
    }
}

I have tried searching for other libraries to use or other ways but couldn't achieve this.

I also tried using apache commons library which does the job as: test.zip -> tempfolder.zip (password protection is done at this level) -> test folder -> test1.txt , test2.txt etc.,

import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import net.lingala.zip4j.model.enums.CompressionLevel;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class APACHECOMMONS2 {

    public static void main(String[] args) {
        String sourceFolder = "<sourcepath>";
         String zipFilePath = "<destination_path>";
        String password = "<password>";
        
        System.out.println("source folder: " + sourceFolder);
        System.out.println("zip file path: " + zipFilePath);
        System.out.println("password: " + password);

        try {
            zipFolderWithPassword(sourceFolder, zipFilePath, password);
            System.out.println("Created password-protected zip file: " + zipFilePath);
        } catch (IOException  e) {
            e.printStackTrace();
        }
    }

    public static void zipFolderWithPassword(String sourceFolderPath, String zipFilePath, String password) throws IOException, ZipException {
        // Step 1: Create a temporary zip file using Apache Commons Compress
        File tempZipFile = File.createTempFile("temp", ".zip");
        System.out.println(tempZipFile.getPath());
        try (ZipArchiveOutputStream archiveOutputStream = new ZipArchiveOutputStream(new FileOutputStream(tempZipFile))) {
            File folderToZip = new File(sourceFolderPath);
            addFolderToZip(archiveOutputStream, folderToZip, folderToZip.getName());
        }

        // Step 2: Create the final password-protected zip file using Zip4j
        ZipFile zipFile = new ZipFile(zipFilePath, password.toCharArray());
        ZipParameters parameters = new ZipParameters();
        parameters.setCompressionLevel(CompressionLevel.NORMAL);
        parameters.setEncryptFiles(true);
        parameters.setEncryptionMethod(EncryptionMethod.AES);

        zipFile.addFile(tempZipFile, parameters);

        // Step 3: Clean up the temporary zip file
        FileUtils.deleteQuietly(tempZipFile);
    }

    private static void addFolderToZip(ZipArchiveOutputStream archiveOutputStream, File folder, String basePath) throws IOException {
        File[] files = folder.listFiles();
        if (files != null) {
            for (File file : files) {
                String entryName = basePath + "/" + file.getName();
                System.out.println("file name: " +entryName);
                if (file.isDirectory()) {
                      System.out.println("file is a directory");
                   addFolderToZip(archiveOutputStream, file, entryName);
                } else {
                      System.out.println("not a directory");
                    ArchiveEntry entry = new ZipArchiveEntry(file, entryName);
                    archiveOutputStream.putArchiveEntry((ZipArchiveEntry) entry);
                    try (FileInputStream inputStream = new FileInputStream(file)) {
                        IOUtils.copy(inputStream, archiveOutputStream);
                    }
                   archiveOutputStream.closeArchiveEntry();
                }
            }
        }
    }
}

I found certain relevant questions from the past and tried out the solution but it seems to be old and many solutions that I tried used methods which are deprecated now.

It would be helpful if someone can suggest a solution how this protection can be done at folder level or if there are any other libraries which can do the job.

Thanks in advance.

Upvotes: 0

Views: 121

Answers (0)

Related Questions