Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Java - Jak jednoduše ověřit správnost hesla u archivu?

Dobrý den,

Ryze pro příklad jsem vytvořil tento kód

var filechooser = new FileChooser();
filechooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("zipfile", "*.zip"));
var archive = filechooser.showOpenDialog(null);
try {
    if (new ZipFile(archive).isEncrypted()) {
        System.out.println(correctPassword(archive, "cat.666"));
        System.out.println(correctPassword(archive, "cat_666"));
    } else {
        System.out.println("Without password");
    }
} catch (ZipException ex) {
}

public static String correctPassword(File archive, String password) {
    try {
        var fileHeaders = new ZipFile(archive).getFileHeaders();
        var smallest_size = fileHeaders.stream().map(f -> f.getComssedSize()).min(Long::compare).get();
        var smallest_file = fileHeaders.stream().filter(f -> f.getCompressedSize() == smallest_size).findFirst().get();
        new ZipFile(archive, password.toCharArray()).extractFile(smallest_file, "/tmp_directory");
        FileUtils.deleteDirectory(new File("C:/tmp_directory"));
    } catch (ZipException ex) {
        return password + " is not correct";
    } catch (IOException ex) {
        System.out.println("bad path");
    }
    return password + " is correct";
}

Sice to funguje, ale jsou tam dva základní problémy

1. Abych ověřil správnost hesla (pomocí knihovny zip4j), musím to extrahovat. Sice jsem to zjednodušil tak, aby extrahoval pouze jeden soubor a dokonce ten nejmenší, avšak jeho výběr je zbytečně složitý.

2. Smazání celé složky s extrahovaným souborem provádím pomocí knihovny Commons IO. Problém je, že je tam absolutní cesta a ještě musím v případě přejmenování složky to upravit na dvou místech.

Jak to, prosím Vás, zjednoduším?

Děkuji

PS. Čistě pro testování jsem vytvořil zip archiv se třemi soubory s heslem cat_666

Předmět Autor Datum
Co třeba nějak takhle? public static boolean verifyZipPassword(ZipFile zipFile, String password) {…
Wikan 26.07.2023 07:38
Wikan
Sorry za opožděnou odpověď. Bavíme se o stejné knihovně, prosím? Pro použití ZipArchiveEntry musím…
MichalDM 07.08.2023 23:59
MichalDM
Určitě? ZipFile.getEntries() ZipFile.canReadEntryData(ZipArchiveEntry ze)
Wikan 08.08.2023 07:59
Wikan
Určitě? Ano, ta moje nemá, protože jste skutečně použil jinou knihovnu. Zatímco já jsem použil zip4… poslední
MichalDM 08.08.2023 20:46
MichalDM
Muzes pouzit temp slozku operacniho systemu, nebo je tu jeste moznost mazat onExit... https://www.b…
MaSo 26.07.2023 10:36
MaSo

Co třeba nějak takhle?

public static boolean verifyZipPassword(ZipFile zipFile, String password) {
    try {
        Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
        ZipArchiveEntry smallestEntry = null;

        while (entries.hasMoreElements()) {
            ZipArchiveEntry entry = entries.nextElement();
            if (smallestEntry == null || entry.getSize() < smallestEntry.getSize()) {
                smallestEntry = entry;
            }
        }

        if (smallestEntry != null) {
            return zipFile.canReadEntryData(smallestEntry, password);
        }

        return true;
    } catch (IOException e) {
        return false;
    }
}

Určitě?

Ano, ta moje nemá, protože jste skutečně použil jinou knihovnu. Zatímco já jsem použil zip4j z net.lingala, Vy zip z commons.compress.

Nevím, jak moc se tyhle knihovny liší. Každopádně, i tak kód nelze použít. Jednak Vámi použitá knihovna nemá žádnou jednoduchou metodu pro ověření, jestli je archiv zaheslovaný. (určitě to jde, ale nevím jak)

ZipFile.canReadEntryData(ZipArchiveEntry ze)

A hlavně, metoda canReadEntryData má pouze jeden parametr, ale v kódu ho voláte se dvěma.

Zpět do poradny Odpovědět na původní otázku Nahoru