Skip to content

Comments

[DRAFT][WIP]Add Zip Archives password support#122093

Draft
alinpahontu2912 wants to merge 58 commits intodotnet:mainfrom
alinpahontu2912:zip_password
Draft

[DRAFT][WIP]Add Zip Archives password support#122093
alinpahontu2912 wants to merge 58 commits intodotnet:mainfrom
alinpahontu2912:zip_password

Conversation

@alinpahontu2912
Copy link
Member

@alinpahontu2912 alinpahontu2912 commented Dec 2, 2025

Fixes #1545

Big Milestones and status:

  • Read Encrypted Entries (ZipCrypto, WinZip AES)
  • Create Encrypted Entries (ZipCrypto, Winzip AES)
  • Update Mode
  • Add runtime assets for checking compat with WinRar/7zip/WinZip/etc
  • Security check for Cryptography methods
  • Final API design

@rzikm rzikm self-requested a review December 11, 2025 12:22
Copy link
Member

@rzikm rzikm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, some minor nits.

Copilot AI review requested due to automatic review settings February 4, 2026 10:13
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings February 6, 2026 12:17
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 6 comments.

Copilot AI review requested due to automatic review settings February 9, 2026 13:24
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 6 comments.

Copilot AI review requested due to automatic review settings February 13, 2026 10:30
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 8 comments.

Copilot AI review requested due to automatic review settings February 16, 2026 11:19
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 1 comment.

Comment on lines +243 to +270
public async Task<Stream> OpenAsync(string password, EncryptionMethod encryptionMethod, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfInvalidArchive();
if (string.IsNullOrEmpty(password))
{
throw new ArgumentNullException(nameof(password), SR.EmptyPassword);
}

switch (_archive.Mode)
{
case ZipArchiveMode.Read:
if (!IsEncrypted)
{
throw new InvalidDataException(SR.EntryNotEncrypted);
}
return await OpenInReadModeAsync(checkOpenable: true, cancellationToken, password.AsMemory()).ConfigureAwait(false);
case ZipArchiveMode.Create:
return OpenInWriteMode(password, encryptionMethod);
case ZipArchiveMode.Update:
default:
Debug.Assert(_archive.Mode == ZipArchiveMode.Update);
if (!IsEncrypted)
{
throw new InvalidDataException(SR.EntryNotEncrypted);
}
return await OpenInUpdateModeAsync(loadExistingContent: true, cancellationToken, password).ConfigureAwait(false);
}
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OpenAsync(string password, EncryptionMethod encryptionMethod, ...) currently allows Read/Update modes and ignores encryptionMethod, which contradicts the sync Open(string password, EncryptionMethod) behavior (Read throws; Update throws). This can lead to callers thinking they’re controlling encryption when they aren’t. Align the async overload with the sync contract (only Create mode should accept an encryption method; Read/Update should throw the same exceptions as the sync overload).

Copilot uses AI. Check for mistakes.

// Derive keys using PBKDF2
int maxPasswordByteCount = Encoding.UTF8.GetMaxByteCount(password.Length);
Span<byte> passwordBytes = stackalloc byte[maxPasswordByteCount];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential stack overflow if the length of password isn't constrained.

{
int saltSize = GetSaltSize(keySizeBits);
int keySizeBytes = keySizeBits / 8;
int expectedSize = saltSize + keySizeBytes + keySizeBytes + 2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cryptographic code should normally be within a checked block to help avoid edge case misuse.

Can you instead create a shared structure or tuple for all of this? That way you won't have to parse it every time you open a file, and it means you can consolidate all of the validation logic to the initial tuple creation rather than have the logic spread out across lots of different methods: this method, plus WrapWithDecryptionIfNeeded, plus CreateKey.

}

// Verify the salt matches
Debug.Assert(fileSalt.AsSpan().SequenceEqual(expectedSalt), "Salt mismatch - key material does not match this entry.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Debug.Assert rather than a proper runtime check?

}

// Compare the first 10 bytes of the expected hash
if (!storedAuth.AsSpan().SequenceEqual(expectedAuth.AsSpan(0, 10)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably use FixedTimeEquals (https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.cryptographicoperations.fixedtimeequals). Consider replacing all uses of SequenceEqual in this class with calls to FixedTimeEquals if appropriate.


private void IncrementCounter()
{
// WinZip AES treats the entire 16-byte block as a little-endian 128-bit integer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use a proper UInt128 field instead? You can use BinaryPrimitives to convert it to and from a little-endian binary representation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add password to ZipArchive

4 participants