1. 程式人生 > 實用技巧 >暴力破解壓縮包(不可用)

暴力破解壓縮包(不可用)

引入依賴,方便解壓加密的壓縮包

        <!-- 解壓壓縮包相關的依賴 -->
        <dependency>
            <groupId>net.lingala.zip4j</groupId>
            <artifactId>zip4j</artifactId>
            <version>2.6.1</version>
        </dependency>

        <!-- guava 工具類,可以不引入 -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>22.0</version>
        </dependency>

迴圈嘗試破解(效率太低。。。)

package com.qiankai.io;

import com.google.common.base.Stopwatch;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import org.apache.commons.lang3.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * 破解壓縮包
 *
 * @author kai_qian
 * @version v1.0
 * @since 2020/08/04 16:47
 */
public class ZipMain {


    /**
     * 密碼中可能存在的字元
     */
    public static char[] chars = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            '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',
            '.', ',', '@'};

    public static void main(String[] args) {
        String filePath = "D:\\Users\\Desktop\\aa.zip";
        String outputPath = "D:\\Users\\Desktop\\aaFolder";
        crackZip(filePath, outputPath, 3);// n>3 以後耗時太長
    }

    public static void crackZip(String filePath, String outputPath, int n) {
        ZipFile zipFile = new ZipFile(filePath);
        for (int i = 1; i <= n; i++) {
            Stopwatch stopwatch = Stopwatch.createStarted();
            generatePassword(zipFile, "", outputPath, i);
            long nanos = stopwatch.elapsed(TimeUnit.MILLISECONDS);
            System.out.println(i+"位密碼,總耗時:" + nanos + "ms");
        }

    }

    /**
     * 窮舉密碼解壓
     * @param zipFile 壓縮包檔案
     * @param pwd 上一次嘗試的密碼
     * @param outputPath 檔案輸出路徑
     * @param n 密碼位數
     * @return
     */
    private static boolean generatePassword(ZipFile zipFile, String pwd, String outputPath, int n) {
        if (n == 0) {
            return false;
        }
        System.out.println("n="+n);
        for (char ch : chars) {
            String newPwd = pwd + ch;
//            Stopwatch stopwatch = Stopwatch.createStarted();
            boolean success = extractFiles(zipFile, newPwd, outputPath);
//            long nanos = stopwatch.elapsed(TimeUnit.MILLISECONDS);
//            System.out.println("解壓耗時:" + nanos + "ms");
            if (success) {
                return true;
            }
            if (n > 0) {
                boolean isSuccess = generatePassword(zipFile, newPwd, outputPath, n - 1);
                if (isSuccess) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 解壓檔案
     *
     * @param zipFile    壓縮包檔案
     * @param password   壓縮包密碼
     * @param outputPath 解壓後的檔案路徑
     * @return 返回是否解壓成功
     */
    private static boolean extractFiles(ZipFile zipFile, String password, String outputPath) {
        try {
            if (StringUtils.isNotEmpty(password) && zipFile.isEncrypted()) {
                // if yes, then set the password for the zip file
                zipFile.setPassword(password.toCharArray());
            }
            zipFile.extractAll(outputPath);

        } catch (ZipException e) {
            System.out.println("使用密碼:" + password + " 驗證," + e.getMessage());
            return false;
        }
        return true;
    }

}

迴圈嘗試密碼,可以自定義chars中的字元,由於是窮舉密碼,chars越大效率越低。
解壓密碼大於3位以後,效率極低,這個程式碼也就是寫著玩一玩了。。。