[DRAFT][WIP]Add Zip Archives password support#122093
Draft
alinpahontu2912 wants to merge 66 commits intodotnet:mainfrom
Draft
[DRAFT][WIP]Add Zip Archives password support#122093alinpahontu2912 wants to merge 66 commits intodotnet:mainfrom
alinpahontu2912 wants to merge 66 commits intodotnet:mainfrom
Conversation
…assword and unprotected
… with cryptography lib
This was referenced Dec 2, 2025
Open
src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509Handles.Unix.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.Async.cs
Outdated
Show resolved
Hide resolved
...O.Compression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/tests/ZipCryptoStreamWrappedConformanceTests.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.Async.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/WinZipAesStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/WinZipAesStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/WinZipAesStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/WinZipAesStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/WinZipAesStream.cs
Outdated
Show resolved
Hide resolved
bartonjs
requested changes
Mar 4, 2026
Member
There was a problem hiding this comment.
General feedback:
- Secrets (including an input password) should never be copied to the heap, unless it's utterly impractical.
- Secrets (including an input password) should also only minimally be copied around on the stack.
- Copied secrets should be cleared.
- Avoid having cryptographic keys (HMAC, AES, etc) stored in arrays.
GitHub's current UI is making this change hard to holistically review, and it's marked as draft, so I've only sprinkled in the most important comments.
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipCryptoStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipCryptoStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipCryptoStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipCryptoStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipCryptoStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/WinZipAesStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/WinZipAesStream.cs
Show resolved
Hide resolved
Comment on lines
+415
to
+423
| private static void XorBytes(Span<byte> dest, ReadOnlySpan<byte> src) | ||
| { | ||
| Debug.Assert(dest.Length <= src.Length); | ||
|
|
||
| for (int i = 0; i < dest.Length; i++) | ||
| { | ||
| dest[i] ^= src[i]; | ||
| } | ||
| } |
Member
There was a problem hiding this comment.
This undoubtedly could be vectorized to go faster, if you expect the operation to generally be bigger than a few bytes. Even just doing something like
Span<ulong> destUL = Marshal.As<byte, ulong>(dest);
ReadOnlySpan<ulong> srcUL = Marshal.As<byte, ulong>(src);
XorUL(destUL, srcUL);
for (int i = destUL.Length * sizeof(ulong); i < dest.Length; i++)
{
...
}(Though I think if src/dest isn't QWORD aligned that might do something less happy on ARM?)
Member
There was a problem hiding this comment.
Might be premature, but if we want to vectorize this, then approach with something like Vector<byte> might be better.
src/libraries/System.IO.Compression/src/System/IO/Compression/WinZipAesStream.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression.ZipFile/ref/System.IO.Compression.ZipFile.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.Async.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.Async.cs
Outdated
Show resolved
Hide resolved
...O.Compression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipCryptoStream.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipCryptoStream.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/WinZipAesStream.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/WinZipAesStream.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/tests/ZipCryptoStreamWrappedConformanceTests.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs
Outdated
Show resolved
Hide resolved
...tem.IO.Compression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchive.Extract.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Compression.ZipFile/src/System/IO/Compression/ZipFile.Extract.cs
Show resolved
Hide resolved
....Compression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchive.Extract.Async.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/tests/ZipCryptoStreamConformanceTests.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/tests/WinZipAesStreamConformanceTests.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/tests/WinZipAesStreamConformanceTests.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.Async.cs
Outdated
Show resolved
Hide resolved
Comment on lines
+251
to
+254
| if (string.IsNullOrEmpty(password)) | ||
| { | ||
| throw new ArgumentNullException(nameof(password), SR.EmptyPassword); | ||
| } |
Comment on lines
+718
to
+722
| public WinZipAesExtraField(ushort VendorVersion, byte AesStrength, ushort CompressionMethod) | ||
| { | ||
| this.VendorVersion = VendorVersion; | ||
| this.AesStrength = AesStrength; | ||
| this.CompressionMethod = CompressionMethod; |
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs
Show resolved
Hide resolved
Comment on lines
+807
to
+821
| BitFlagValues savedFlags = _generalPurposeBitFlag; | ||
| EncryptionMethod savedEncryption = Encryption; | ||
|
|
||
| // For AES entries: clear Encryption so WriteLocalFileHeaderAsync doesn't create a new | ||
| // AES extra field (the original one in _lhUnknownExtraFields will be used). | ||
| if (savedEncryption is EncryptionMethod.Aes128 or EncryptionMethod.Aes192 or EncryptionMethod.Aes256) | ||
| { | ||
| Encryption = EncryptionMethod.None; | ||
| } | ||
|
|
||
| await WriteLocalFileHeaderAsync(isEmptyFile: _uncompressedSize == 0, forceWrite: true, cancellationToken).ConfigureAwait(false); | ||
|
|
||
| // Restore original state | ||
| _generalPurposeBitFlag = savedFlags; | ||
| Encryption = savedEncryption; |
| /// <exception cref="PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. | ||
| /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.</exception> | ||
| /// <exception cref="DirectoryNotFoundException">The specified path is invalid, (for example, it is on an unmapped drive).</exception> | ||
| /// <exception cref="IOException">An archive entry?s name is zero-length, contains only whitespace, or contains one or more invalid |
| @@ -0,0 +1,106 @@ | |||
| // The .NET Foundation licenses this file to you under the MIT license. | |||
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.Async.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs
Outdated
Show resolved
Hide resolved
Comment on lines
+55
to
+66
| byte[] encryptionKey = new byte[keySizeBytes]; | ||
| Array.Copy(keyMaterial, offset, encryptionKey, 0, keySizeBytes); | ||
| offset += keySizeBytes; | ||
|
|
||
| byte[] hmacKey = new byte[keySizeBytes]; | ||
| Array.Copy(keyMaterial, offset, hmacKey, 0, keySizeBytes); | ||
| offset += keySizeBytes; | ||
|
|
||
| byte[] passwordVerifier = new byte[2]; | ||
| Array.Copy(keyMaterial, offset, passwordVerifier, 0, 2); | ||
|
|
||
| return new WinZipAesKeyMaterial(salt, encryptionKey, hmacKey, passwordVerifier, keySizeBits); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1545
Big Milestones and status: