3 Stimmen

Testen Sie die Richtigkeit des ZIP-Passworts in vb.net

Ich möchte testen, ob eine ZIP-Datei ein bestimmtes Passwort hat, und zwar in VB.NET. Wie kann ich eine Funktion wie check_if_zip_pass(datei, pass) As Boolean erstellen?

Es scheint nichts im .NET-Framework zu geben, das dies bereits tut, es sei denn, ich übersehe etwas unglaublich Offensichtliches.

Diese Methode sollte KEINE Dateien extrahieren, sondern nur True zurückgeben, wenn das versuchte Passwort gültig ist, und False, wenn nicht.

3voto

Cheeso Punkte 184210

Verwenden Sie eine Bibliothek eines Drittanbieters, wie DotNetZip. Beachten Sie, dass Passwörter in Zip-Dateien auf Einträge angewendet werden und nicht auf die gesamte Zip-Datei. Daher ergibt Ihr Test nicht ganz Sinn.

Ein Grund, warum WinZip möglicherweise die Zip-Datei nicht entpacken kann, ist, dass der allererste Eintrag mit einem Passwort geschützt ist. Es könnte der Fall sein, dass nur einige Einträge durch ein Passwort geschützt sind und andere nicht. Es könnte auch sein, dass unterschiedliche Passwörter für verschiedene Einträge verwendet werden. Sie müssen entscheiden, was Sie mit diesen Möglichkeiten tun möchten.

Eine Option besteht darin anzunehmen, dass für Einträge in der Zip-Datei, die verschlüsselt sind, nur ein Passwort verwendet wird. (Dies ist nicht durch die Zip-Spezifikation vorgeschrieben) In diesem Fall ist hier ein Beispielcode zum Überprüfen des Passworts. Es gibt keine Möglichkeit, ein Passwort zu überprüfen, ohne die Entschlüsselung durchzuführen. Daher entschlüsselt dieser Code und extrahiert in Stream.Null.

public bool CheckZipPassword(string filename, string password)
{
    bool success = false;
    try
    {
        using (ZipFile zip1 = ZipFile.Read(filename))
        {
            var bitBucket = System.IO.Stream.Null;
            foreach (var e in zip1)
            {
                if (!e.IsDirectory && e.UsesEncryption)
                {
                    e.ExtractWithPassword(bitBucket, password);
                }
            }
        }
        success = true;    
    }
    catch(Ionic.Zip.BadPasswordException) { }
    return success;
}

Hoppla! Ich denke in C#. In VB.NET wäre dies:

    Public Function CheckZipPassword(filename As String, password As String) As System.Boolean
        Dim success As System.Boolean = False
        Try
            Using zip1 As ZipFile = ZipFile.Read(filename)
                Dim bitBucket As System.IO.Stream = System.IO.Stream.Null
                Dim e As ZipEntry
                For Each e in zip1
                    If (Not e.IsDirectory) And e.UsesEncryption Then
                        e.ExtractWithPassword(bitBucket, password)
                    End If
                Next
             End Using
             success = True
        Catch ex As Ionic.Zip.BadPasswordException
        End Try
        Return success
    End Function

2voto

Zachary Punkte 6482

Ich benutze SharpZipLib in .NET, um dies zu tun, hier ist ein Link zu ihrem Wiki mit einer Hilfsfunktion zum Entpacken von passwortgeschützten Zip-Dateien. Unten finden Sie eine Kopie der Hilfsfunktion für VB.NET.

Imports ICSharpCode.SharpZipLib.Core
Imports ICSharpCode.SharpZipLib.Zip

Public Sub ExtractZipFile(archiveFilenameIn As String, password As String, outFolder As String)
    Dim zf As ZipFile = Nothing
    Try
        Dim fs As FileStream = File.OpenRead(archiveFilenameIn)
        zf = New ZipFile(fs)
        If Not [String].IsNullOrEmpty(password) Then    ' AES-verschlüsselte Einträge werden automatisch behandelt
            zf.Password = password
        End If
        For Each zipEntry As ZipEntry In zf
            If Not zipEntry.IsFile Then     ' Verzeichnisse ignorieren
                Continue For
            End If
            Dim entryFileName As [String] = zipEntry.Name
            ' Um den Ordner aus dem Eintrag zu entfernen:- entryFileName = Path.GetFileName(entryFileName);
            ' Optional hier Entry-Namen gegen eine Auswahlliste abgleichen, um nach Bedarf zu überspringen.
            ' Die entpackte Länge ist in der zipEntry.Size-Eigenschaft verfügbar.

            Dim buffer As Byte() = New Byte(4095) {}    ' 4K ist optimal
            Dim zipStream As Stream = zf.GetInputStream(zipEntry)

            ' Hier Ausgabedateinamen nach Wunsch bearbeiten.
            Dim fullZipToPath As [String] = Path.Combine(outFolder, entryFileName)
            Dim directoryName As String = Path.GetDirectoryName(fullZipToPath)
            If directoryName.Length > 0 Then
                Directory.CreateDirectory(directoryName)
            End If

            ' Datei in gepufferten Teilen entzippen. Dies ist genauso schnell wie das Entpacken in einen Puffer in voller Größe
            ' der Datei, verbraucht jedoch keinen Speicher.
            ' Das "Using" wird den Stream schließen, auch wenn eine Ausnahme auftritt.
            Using streamWriter As FileStream = File.Create(fullZipToPath)
                StreamUtils.Copy(zipStream, streamWriter, buffer)
            End Using
        Next
    Finally
        If zf IsNot Nothing Then
            zf.IsStreamOwner = True     ' Macht das Schließen auch den zugrunde liegenden Stream
            ' Stellen Sie sicher, dass wir Ressourcen freigeben
            zf.Close()
        End If
    End Try
End Sub

Zum Testen könnten Sie einen Dateivergleich erstellen, der die Datei betrachtet, bevor sie gezippt wird, und erneut, nachdem sie entzippt wurde (Größe, Datum usw.). Sie könnten sogar den Inhalt vergleichen, wenn Sie eine einfache Testdatei verwenden wollten, wie eine Datei mit dem Text "TEST" darin. Viele Möglichkeiten, je nachdem, wie viel und wie weit Sie testen möchten.

1voto

Cᴏʀʏ Punkte 101076

Es ist nicht viel im Framework dafür eingebaut. Hier ist ein großer schlampiger Haufen, den Sie mit der SharpZipLib-Bibliothek versuchen könnten:

public static bool CheckIfCorrectZipPassword(string fileName, string tempDirectory, string password)
{
    byte[] buffer= new byte[2048];
    int n;
    bool isValid = true;

    using (var raw = File.Open(fileName, FileMode.Open, FileAccess.Read))
    {
        using (var input = new ZipInputStream(raw))
        {
            ZipEntry e;
            while ((e = input.GetNextEntry()) != null)
            {
                input.Password = password;
                if (e.IsDirectory) continue;
                string outputPath = Path.Combine(tempDirectory, e.FileName);

                try
                {
                    using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
                    {
                        while ((n = input.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            output.Write(buffer, 0, n);
                        }
                    }
                }
                catch (ZipException ze)
                {
                    if (ze.Message == "Invalid Password")
                    {
                        isValid = false;
                    }
                }
                finally
                {
                    if (File.Exists(outputPath))
                    {
                        // Vorsicht, das kann Ausnahmen auslösen
                        File.Delete(outputPath);
                    }
                }
                if (!isValid)
                {
                    break;
                }
            }
        }
    }
    return isValid;
}

Entschuldigung für das C#; sollte relativ einfach in VB.NET zu konvertieren sein.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X