web-dev-qa-db-fra.com

Fichier Zip protégé par mot de passe en java

J'ai créé un fichier Zip en utilisant Java comme l'extrait ci-dessous

import Java.io.*;
import Java.util.Zip.*;

public class ZipCreateExample {
  public static void main(String[] args) throws IOException {
    System.out.print("Please enter file name to Zip : ");
    BufferedReader input = new BufferedReader
        (new InputStreamReader(System.in));
    String filesToZip = input.readLine();
    File f = new File(filesToZip);
    if(!f.exists()) {
      System.out.println("File not found.");
      System.exit(0);
    }
    System.out.print("Please enter Zip file name : ");
    String zipFileName = input.readLine();
    if (!zipFileName.endsWith(".Zip"))
      zipFileName = zipFileName + ".Zip";
    byte[] buffer = new byte[18024];
    try {
      ZipOutputStream out = new ZipOutputStream
          (new FileOutputStream(zipFileName));
      out.setLevel(Deflater.DEFAULT_COMPRESSION);
      FileInputStream in = new FileInputStream(filesToZip);
      out.putNextEntry(new ZipEntry(filesToZip));
      int len;
      while ((len = in.read(buffer)) > 0) {
        out.write(buffer, 0, len);
      }
      out.closeEntry();
      in.close();
      out.close();
    } catch (IllegalArgumentException iae) {
      iae.printStackTrace();
      System.exit(0);
    } catch (FileNotFoundException fnfe) {
      fnfe.printStackTrace();
      System.exit(0);
    } catch (IOException ioe) {
      ioe.printStackTrace();
      System.exit(0);
    }
  }
}

Maintenant, je veux que lorsque je clique sur le fichier Zip, il devrait m'inviter à taper le mot de passe, puis décompresser le fichier Zip. S'il vous plaît toute aide, comment dois-je aller plus loin?

24
Edward

Standard Java API ne prend pas en charge les fichiers Zip protégés par mot de passe. Heureusement, les gars ont déjà mis en œuvre une telle capacité pour nous. Veuillez lire cet article qui explique comment créer un Zip protégé par mot de passe: http://Java.sys-con.com/node/1258827

20
AlexR

Essayez le code suivant basé sur Zip4j :

import net.lingala.Zip4j.core.ZipFile;
import net.lingala.Zip4j.exception.ZipException;
import net.lingala.Zip4j.model.ZipParameters;
import net.lingala.Zip4j.util.Zip4jConstants;
import org.Apache.commons.io.FilenameUtils;

import Java.io.File;

public class Zipper
{
    private String password;
    private static final String EXTENSION = "Zip";

    public Zipper(String password)
    {
        this.password = password;
    }

    public void pack(String filePath) throws ZipException
    {
        ZipParameters zipParameters = new ZipParameters();
        zipParameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
        zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_ULTRA);
        zipParameters.setEncryptFiles(true);
        zipParameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
        zipParameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
        zipParameters.setPassword(password);
        String baseFileName = FilenameUtils.getBaseName(filePath);
        String destinationZipFilePath = baseFileName + "." + EXTENSION;
        ZipFile zipFile = new ZipFile(destinationZipFilePath);
        zipFile.addFile(new File(filePath), zipParameters);
    }

    public void unpack(String sourceZipFilePath, String extractedZipFilePath) throws ZipException
    {
        ZipFile zipFile = new ZipFile(sourceZipFilePath + "." + EXTENSION);

        if (zipFile.isEncrypted())
        {
            zipFile.setPassword(password);
        }

        zipFile.extractAll(extractedZipFilePath);
    }
}

FilenameUtils est de Apache Commons IO .

Exemple d'utilisation:

public static void main(String[] arguments) throws ZipException
{
    Zipper zipper = new Zipper("password");
    zipper.pack("encrypt-me.txt");
    zipper.unpack("encrypt-me", "D:\\");
}
17
BullyWiiPlaza

Un exemple de code ci-dessous protégera votre fichier par Zip et mot de passe. Ce service REST accepte les octets du fichier d'origine. Il zippe le tableau d'octets et le mot de passe le protège. Ensuite, il envoie des octets de fichier zippé protégé par mot de passe en réponse. Le code est un exemple d'envoi et de réception octets binaires vers et depuis un service REST, et aussi de compresser un fichier avec un mot de passe. Les octets sont compressés du flux, donc aucun fichier n'est jamais stocké sur le serveur.

  • Utilise l'API JAX-RS à l'aide de l'API Jersey en Java
  • Le client utilise l'API client Jersey.
  • Utilise la bibliothèque open source Zip4j 1.3.2 et Apache commons io.


    @PUT
    @Path("/bindata/protect/qparam")
    @Consumes(MediaType.APPLICATION_OCTET_STREAM)
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response zipFileUsingPassProtect(byte[] fileBytes, @QueryParam(value = "pass") String pass,
            @QueryParam(value = "inputFileName") String inputFileName) {

        System.out.println("====2001==== Entering zipFileUsingPassProtect");
        System.out.println("fileBytes size = " + fileBytes.length);
        System.out.println("password = " + pass);
        System.out.println("inputFileName = " + inputFileName);

        byte b[] = null;
        try {
            b = zipFileProtected(fileBytes, inputFileName, pass);
        } catch (IOException e) {
            e.printStackTrace();
            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
        }
        System.out.println(" ");
        System.out.println("++++++++++++++++++++++++++++++++");
        System.out.println(" ");
        return Response.ok(b, MediaType.APPLICATION_OCTET_STREAM)
                .header("content-disposition", "attachment; filename = " + inputFileName + ".Zip").build();

    }

    private byte[] zipFileProtected(byte[] fileBytes, String fileName, String pass) throws IOException {

        ByteArrayInputStream inputByteStream = null;
        ByteArrayOutputStream outputByteStream = null;
        net.lingala.Zip4j.io.ZipOutputStream outputZipStream = null;

        try {
            //write the Zip bytes to a byte array
            outputByteStream = new ByteArrayOutputStream();
            outputZipStream = new net.lingala.Zip4j.io.ZipOutputStream(outputByteStream);

            //input byte stream to read the input bytes
            inputByteStream = new ByteArrayInputStream(fileBytes);

            //init the Zip parameters
            ZipParameters zipParams = new ZipParameters();
            zipParams.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
            zipParams.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
            zipParams.setEncryptFiles(true);
            zipParams.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
            zipParams.setPassword(pass);
            zipParams.setSourceExternalStream(true);
            zipParams.setFileNameInZip(fileName);

            //create Zip entry
            outputZipStream.putNextEntry(new File(fileName), zipParams);
            IOUtils.copy(inputByteStream, outputZipStream);
            outputZipStream.closeEntry();

            //finish up
            outputZipStream.finish();

            IOUtils.closeQuietly(inputByteStream);
            IOUtils.closeQuietly(outputByteStream);
            IOUtils.closeQuietly(outputZipStream);

            return outputByteStream.toByteArray();

        } catch (ZipException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(inputByteStream);
            IOUtils.closeQuietly(outputByteStream);
            IOUtils.closeQuietly(outputZipStream);
        }
        return null;
    }

Test unitaire ci-dessous:


    @Test
    public void testPassProtectZip_with_params() {
        byte[] inputBytes = null;
        try {
            inputBytes = FileUtils.readFileToByteArray(new File(inputFilePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("bytes read into array. size = " + inputBytes.length);

        Client client = ClientBuilder.newClient();

        WebTarget target = client.target("http://localhost:8080").path("filezip/services/Zip/bindata/protect/qparam");
        target = target.queryParam("pass", "mypass123");
        target = target.queryParam("inputFileName", "any_name_here.pdf");

        Invocation.Builder builder = target.request(MediaType.APPLICATION_OCTET_STREAM);

        Response resp = builder.put(Entity.entity(inputBytes, MediaType.APPLICATION_OCTET_STREAM));
        System.out.println("response = " + resp.getStatus());
        Assert.assertEquals(Status.OK.getStatusCode(), resp.getStatus());

        byte[] zipBytes = resp.readEntity(byte[].class);
        try {
            FileUtils.writeByteArrayToFile(new File(responseFilePathPasswordZipParam), zipBytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

N'hésitez pas à utiliser et à modifier. Veuillez me faire savoir si vous trouvez des erreurs. J'espère que cela t'aides.

Edit 1 - Utilisation de QueryParam mais vous pouvez utiliser HeaderParam pour PUT à la place pour masquer le mot de passe à la vue. Modifiez la méthode de test en conséquence.

Edit 2 - REST est filezip/services/Zip/bindata/protect/qparam

filezip est le nom de la guerre. services est le mappage d'URL dans web.xml. Zip est une annotation de chemin de classe. bindata/protect/qparam est l'annotation de chemin au niveau de la méthode.

11
RuntimeException

Il n'y a pas par défaut Java API pour créer un fichier protégé par mot de passe. Il y a un autre exemple sur la façon de le faire ici .

1
Juliano