在vb.net中测试zip密码的正确性

发布于 2024-11-14 19:27:00 字数 230 浏览 1 评论 0原文

我想测试 zip 在 vb.net 中是否有特定的密码。如何创建像 check_if_zip_pass(file, pass) As Boolean 这样的函数?

我似乎无法在 .net 框架中找到任何已经执行此操作的内容,除非我遗漏了一些非常明显的内容。

此方法不应提取文件,仅在尝试的传递有效时返回 True,否则返回 False

I want to test if a zip has a particular password in vb.net. How can I create a function like check_if_zip_pass(file, pass) As Boolean?

I can't seem to find anything in the .net framework that does this already, unless I'm missing something incredibly obvious.

This method should NOT extract the files, only return True if the attempted pass is valid and False if not.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

天涯离梦残月幽梦 2024-11-21 19:27:01

我在 .NET 中使用 SharpZipLib 来执行此操作,这里有一个 链接 到他们的 wiki具有用于解压缩受密码保护的 zip 文件的帮助函数。下面是 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 encrypted entries are handled automatically
            zf.Password = password
        End If
        For Each zipEntry As ZipEntry In zf
            If Not zipEntry.IsFile Then     ' Ignore directories
                Continue For
            End If
            Dim entryFileName As [String] = zipEntry.Name
            ' to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
            ' Optionally match entrynames against a selection list here to skip as desired.
            ' The unpacked length is available in the zipEntry.Size property.

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

            ' Manipulate the output filename here as desired.
            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

            ' Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
            ' of the file, but does not waste memory.
            ' The "Using" will close the stream even if an exception occurs.
            Using streamWriter As FileStream = File.Create(fullZipToPath)
                StreamUtils.Copy(zipStream, streamWriter, buffer)
            End Using
        Next
    Finally
        If zf IsNot Nothing Then
            zf.IsStreamOwner = True     ' Makes close also shut the underlying stream
            ' Ensure we release resources
            zf.Close()
        End If
    End Try
End Sub

为了进行测试,您可以创建一个文件比较,在压缩之前和解压之后再次查看文件(大小、日期等...)。如果您想使用简单的测试文件(例如内部带有文本“TEST”的文件),您甚至可以比较内容。有很多选择,取决于您想要测试的程度和程度。

I use SharpZipLib in .NET to do this, here is a link to their wiki with a helper function for unzipping password protected zip files. Below is a copy of the helper function for 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 encrypted entries are handled automatically
            zf.Password = password
        End If
        For Each zipEntry As ZipEntry In zf
            If Not zipEntry.IsFile Then     ' Ignore directories
                Continue For
            End If
            Dim entryFileName As [String] = zipEntry.Name
            ' to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
            ' Optionally match entrynames against a selection list here to skip as desired.
            ' The unpacked length is available in the zipEntry.Size property.

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

            ' Manipulate the output filename here as desired.
            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

            ' Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
            ' of the file, but does not waste memory.
            ' The "Using" will close the stream even if an exception occurs.
            Using streamWriter As FileStream = File.Create(fullZipToPath)
                StreamUtils.Copy(zipStream, streamWriter, buffer)
            End Using
        Next
    Finally
        If zf IsNot Nothing Then
            zf.IsStreamOwner = True     ' Makes close also shut the underlying stream
            ' Ensure we release resources
            zf.Close()
        End If
    End Try
End Sub

To test, you could create a file compare that looks at the file before it's zipped and again after it has been unzipped (size, date, etc...). You could even compare the contents if you wanted to use a simple test file, like a file with the text "TEST" inside. Lots of choices, depends on how much and how far you want to test.

情泪▽动烟 2024-11-21 19:27:01

框架中并没有内置太多用于执行此操作的内容。这是一个很大的混乱,您可以尝试使用 SharpZipLib 库:

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))
                    {
                        // careful, this can throw exceptions
                        File.Delete(outputPath);
                    }
                }
                if (!isValid)
                {
                    break;
                }
            }
        }
    }
    return isValid;
}

Apologies for the C#;转换为 VB.NET 应该相当简单。

There's not much built into the framework for doing this. Here's a big sloppy mess you could try using the SharpZipLib library:

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))
                    {
                        // careful, this can throw exceptions
                        File.Delete(outputPath);
                    }
                }
                if (!isValid)
                {
                    break;
                }
            }
        }
    }
    return isValid;
}

Apologies for the C#; should be fairly straightforward to convert to VB.NET.

风吹雪碎 2024-11-21 19:27:00

使用第 3 方库,例如 DotNetZip。请记住,zip 文件中的密码适用于条目,而不是整个 zip 文件。所以你的测试不太有意义。

WinZip 可能拒绝解压 zip 文件的一个原因是第一个条目受密码保护。可能只有某些条目受密码保护,而另一些则不受密码保护。不同的条目可能使用不同的密码。您必须决定如何应对这些可能性。

一种选择是假设 zip 文件中加密的任何条目仅使用一个密码。 (zip 规范不要求这样做)在这种情况下,下面是一些用于检查密码的示例代码。如果不进行解密,就无法检查密码。所以这段代码解密并提取到 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;
}

哎呀!我认为在 C# 中。在 VB.NET 中,这将是:

    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

Use a 3rd party library, like DotNetZip. Keep in mind that passwords in zipfiles are applied to entries, not to the entire zip file. So your test doesn't quite make sense.

One reason WinZip may refuse to unpack the zipfile is that the very first entry is protected with a password. It could be the case that only some entries are protected by password, and some are not. It could be that different passwords are used on different entries. You'll have to decide what you want to do about these possibilities.

One option is to suppose that only one password is used on any entries in the zipfile that are encrypted. (This is not required by the zip specification) In that case, below is some sample code to check the password. There is no way to check a password without doing the decryption. So this code decrypts and extracts into 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;
}

Whoops! I think in C#. In VB.NET this would be:

    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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文