LoginSignup
11
13

More than 5 years have passed since last update.

Zip4jでバイト配列を暗号化zip圧縮する

Posted at

目的

Java標準のjava.util.zipは暗号化に対応していません。
なので暗号化zipをしようとすると別途ライブラリが必要になります。
色々試したのですが、結局は一番メジャーらしいzip4jを使うことにしました。

zip4j

公式サイトはこちら
Maven Repositoryはこちら
最新のバージョンは1.3.2のようです。

コード

依存ライブラリを定義

pom.xml
    <dependencies>
        <dependency>
            <groupId>net.lingala.zip4j</groupId>
            <artifactId>zip4j</artifactId>
            <version>1.3.2</version>
        </dependency>
    </dependencies>

暗号化zip部分

このライブラリに限らないのですが、zipエントリを作る際、実際に存在するファイルの属性を取得して利用しているため、バイト配列だけでは直接zipエントリを作成できません。
なので、Fileクラスの匿名クラスを使って対処します。
ただ、階層構造をもったzipファイルを作ろうとすると面倒なので、その場合は一時的にローカル出力したファイルを圧縮した方が楽かもしれません。

Zip.java
package com.company;

import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

public class Zip {

    public byte[] encryptZip(final String fileName, final byte[] input, String password) throws IOException, ZipException {
        ZipParameters parameters = new ZipParameters();
        parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
        parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
        parameters.setEncryptFiles(true);
        parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
        parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
        parameters.setPassword(password);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try (net.lingala.zip4j.io.ZipOutputStream zipOutputStream = new net.lingala.zip4j.io.ZipOutputStream(byteArrayOutputStream)) {
            File file = new File(fileName) {
                @Override
                public boolean exists() {return true;}
                @Override
                public boolean isDirectory() {return false;}
                @Override
                public String getAbsolutePath() {return fileName;}
                @Override
                public boolean isHidden() {return false;}
                @Override
                public long lastModified() {return System.currentTimeMillis();}
                @Override
                public long length() {return input.length;}
            };

            zipOutputStream.putNextEntry(file, parameters);
            zipOutputStream.write(input);
            zipOutputStream.closeEntry();
            zipOutputStream.finish();
        }

        return byteArrayOutputStream.toByteArray();

    }
}

呼び出し

あとはファイル名と暗号化zip圧縮したいバイト配列、パスワードを渡すだけです

Main.java
    public static void main(String[] args) {
        Zip zip = new Zip();
        try {
            byte[] encrypted = zip.encryptZip("hoge.txt", new byte[]{0x30, 0x30}, "testPwd");
            try(FileOutputStream stream = new FileOutputStream(".\test.zip")) {
                stream.write(encrypted);
            }
        } catch (IOException | ZipException e) {
            e.printStackTrace();
        }
    }

全部オンメモリで処理したい場合はこうなるかなと。

11
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
13