ZIPパスワード解析&解読&解除方法。パス強度大丈夫?

パスワード付きで圧縮したZIPファイルのパスワードを忘れてしまい、ZIPのパスワード解析、解読、解除ツールを作って、解凍してみました。簡単なパスワードだったため解凍はできたのですが、改めてパスワードは難しくしないとだめだなと思いました。今回作成したJavaのプログラムのコードを紹介いたします。

目次

1. zip4jで簡単にパスワード付きのZIPが扱える

Javaの場合、zip4jを使用すれば簡単にパスワード付きのZIPが扱えます。今回はこれを使ってZIPパスワード解析&解読&解除ツールを作成してみました。

zip4jの入手先

zip4jは「http://www.lingala.net/zip4j/download.php」からダウンロードできます。

2. ZIPパスワード解析&解読&解除ツールの概要

サンプルはSwingを使用してGUI操作でZIPファイルのパスと解凍先のディレクトリのパスを指定して解凍できるようにしています。もしパスワードがある場合は、パスワードの候補文字列を作成して秒間1000回ほどのパターンを試して、ZIPのパスワードを解析して、解読できた場合は解除して解凍先に出力します。

起動時のイメージ

起動時のイメージです。zipファイルパスのところにパスワード付きのZIPファイルのパスを入力します。出力ディレクトリパスのところに出力するディレクトリのパスを指定して、取得ボタンを押すだけの簡単なものです。

実行後のイメージ

起動時のイメージです。zipファイルパスのところにパスワード付きのZIPファイルのパスを入力します。出力ディレクトリパスのところに出力するディレクトリのパスを指定して、取得ボタンを押すだけの簡単なものです。

解凍したファイルは解凍先ですが、ZIPパスワード解析ツールの下のところに、ループ回数と処理時間、解析したパスワードを表示します。164とか3文字だと6秒で解読して、解除できます。

3. Javaのサンプルコード

今回作成したコードは以下です。コードがわかりやすくなるようになるべく日本語の名前の関数と変数を使ってみました(笑)。

package sample;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;

public class サンプル extends JFrame implements ActionListener{
    private JTextField zipパスエリア;
    private JTextField 出力DIRパスエリア;
    private JLabel メッセージ表示用ラベル;

    public static void main(String args[]){
        サンプル フレーム = new サンプル();
        フレーム.初期処理("ZIPパスワード解析");
        フレーム.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String zipファイルパス = zipパスエリア.getText();
        String 出力ディレクトリ = 出力DIRパスエリア.getText();
        メッセージ表示用ラベル.setText(zip解凍(zipファイルパス, 出力ディレクトリ));
    }

    private void 初期処理(String タイトル){
        setTitle(タイトル);
        setBounds(100, 100, 500, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel パネル = new JPanel();
        zipパスエリア = new JTextField("zipファイルパス", 40);
        出力DIRパスエリア = new JTextField("出力ディレクトリパス", 40);
        JButton button = new JButton("取得");
        button.addActionListener(this);
        メッセージ表示用ラベル = new JLabel();
        パネル.add(zipパスエリア);
        パネル.add(出力DIRパスエリア);
        パネル.add(button);
        this.add(パネル, BorderLayout.CENTER);
        this.add(メッセージ表示用ラベル, BorderLayout.SOUTH);
    }

    private String zip解凍(String zipファイルパス, String 出力ディレクトリ) {
        String パスワード = "";
        long 開始時刻 = System.currentTimeMillis();
        long ループ回数 = 0;

        for (ループ回数 = 0; ループ回数 < 2147483647; ループ回数++) {
            パスワード = 基数変換(ループ回数);

            try {
                ZipFile zipファイル = new ZipFile(zipファイルパス);
                if (zipファイル.isEncrypted()) {
                    zipファイル.setPassword(パスワード);
                }
                zipファイル.extractAll(出力ディレクトリ);
               break;
            } catch (ZipException e) {}
        }
        long 終了時刻 = System.currentTimeMillis();
        return "ループ回数:" + ループ回数 + 
                ", 処理時間:" + (終了時刻 - 開始時刻)/1000  + "秒" + 
                ", パスワード:" + パスワード;
    }

    private static char[] 文字列 = {
    '1','2','3','4','5','6','7','8','9','0',
        'a','b','c','d','e','f','g','h','i',
        'j','k','l','m','n','o','p','q','r',
        's','t','u','v','w','x','y','z',
        'A','B','C','D','E','F','G','H','I',
        'J','K','L','M','N','O','P','Q','R',
        'S','T','U','V','W','X','Y','Z',
        '-','_','.','@'};

    private String 基数変換(long 変換前の数) {
        String 変換後の文字 = "";

        while (true) {
            int 要素番号 = (int)変換前の数 % 文字列.length;
            変換後の文字 = 文字列[要素番号] + 変換後の文字;
            変換前の数 = (変換前の数 / 文字列.length) -1;

            if (変換前の数 < 0) {
                break;
            }
        }
        return 変換後の文字;
    }
}

4. まとめ

今回はパスワードを忘れてしまったことから、簡単なZIPのパスワード解析、解読、解除ツールを作ってみました。このツールでも1秒に1000回試せるので、数字英数字が10+26+26=62文字種とすると、掛け合わせで2文字だと3844で4秒、3文字だと238328で約238秒、4文字だと14776336で約246分、5文字だと916132832で約11日、6文字で1年8か月あれば解読、解除できる感じでした。マルチスレッド、複数マシンとか工夫すればまだまだ相当速度が早くなりそうです。パスワードは記号も含めてもっと長い文字にしないといけないですね。

でも今回は簡単なパスワードにしておいてすくわれました。

更新履歴

  • 2017年03月22日 記事をUPしました。

SNSでもご購読できます。