You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #122093 ("Add Zip Archives password support", merged 2026-07-09, commit 0174483358e) added an unconditionalProjectReference to System.Security.Cryptography from System.IO.Compression, and wired AES/ZipCrypto encryption into the always-reachable ZipArchiveEntry code paths. As a result, the ILLink trimmer now retains System.Security.Cryptography in any trimmed app that uses ZipArchive — even when the app never touches encryption. This is a size regression, and it is especially impactful on browser-wasm, which is the most download-size-sensitive target and where AES zip encryption is already declared unsupported.
Cause
src/libraries/System.IO.Compression/src/System.IO.Compression.csproj now has (line ~114):
The crypto call sites live in a few leaf classes (WinZipAesStream, WinZipAesKeyMaterial, ZipCryptoStream) and are invoked from encryption branches in ZipArchiveEntry.cs / ZipArchiveEntry.Async.cs. Reachable crypto surface includes:
Because ZipArchiveEntry references the WinZipAesStream type (which has a private readonly Aes _aes; field), the crypto assembly stays linked via type metadata regardless of the existing OperatingSystem.IsBrowser() throw-guards that were added inside the leaf classes — those guards make AES correctly throw on browser but do not break the trim linkage.
Size impact
Untrimmed System.Security.Cryptography.dll in the net11 browser-wasm runtime pack is ~670 KB of managed IL (for comparison, System.IO.Compression.dll itself is ~184 KB). The trimmed + Webcil + AOT-native cost that actually ships is smaller than the untrimmed IL but non-trivial: on browser-wasm crypto has no OpenSSL backing, so the managed implementations of AES/HMAC-SHA1/PBKDF2/RNG are what get retained, and the AOT-compiled native contribution to dotnet.native.wasm compounds it. Exact trimmed/AOT delta should be measured with a before/after browser-wasm publish.
Suggested fix
Break the linkage on browser-wasm (and any platform where zip encryption is not supported) by placing foldable OperatingSystem.IsBrowser() guards that throw at the call sites in ZipArchiveEntry(.Async).cs (before the crypto leaf types are referenced), so ILLink constant-folds them and removes the encryption branches as unreachable, dropping System.Security.Cryptography from the closure.
Note this is all-or-nothing: AES is already unsupported on browser, but ZipCryptoStream (legacy ZipCrypto) is currently unguarded and only uses RandomNumberGenerator.Fill + CryptographicOperations.ZeroMemory (both browser-workable), so it independently keeps crypto linked. To fully remove the dependency, ZipCrypto encryption must also be declared unsupported on browser — a small behavior decision for the area owners, defensible given AES is already unsupported there and ZipCrypto is legacy/weak.
Side effect on CI
This regression is also the root cause of the Known Build Error #130540 (ReferenceNewAssemblyRebuildTest — "Expected changed file: driver-gen.c"): the test relied on System.Security.Cryptography being absent from the base app's AOT closure. Now that it is always present, the AOT modules table (driver-gen.c) no longer changes on rebuild. Fixing the trim linkage would also resolve that test (though the test is being hardened separately so it can't rot again).
Summary
PR #122093 ("Add Zip Archives password support", merged 2026-07-09, commit
0174483358e) added an unconditionalProjectReferencetoSystem.Security.CryptographyfromSystem.IO.Compression, and wired AES/ZipCrypto encryption into the always-reachableZipArchiveEntrycode paths. As a result, the ILLink trimmer now retainsSystem.Security.Cryptographyin any trimmed app that usesZipArchive— even when the app never touches encryption. This is a size regression, and it is especially impactful on browser-wasm, which is the most download-size-sensitive target and where AES zip encryption is already declared unsupported.Cause
src/libraries/System.IO.Compression/src/System.IO.Compression.csprojnow has (line ~114):The crypto call sites live in a few leaf classes (
WinZipAesStream,WinZipAesKeyMaterial,ZipCryptoStream) and are invoked from encryption branches inZipArchiveEntry.cs/ZipArchiveEntry.Async.cs. Reachable crypto surface includes:Aes.Create()IncrementalHash.CreateHMAC(HashAlgorithmName.SHA1, ...)Rfc2898DeriveBytes.Pbkdf2(...)(PBKDF2)RandomNumberGenerator.Fill(...)CryptographicOperations.ZeroMemory(...)Because
ZipArchiveEntryreferences theWinZipAesStreamtype (which has aprivate readonly Aes _aes;field), the crypto assembly stays linked via type metadata regardless of the existingOperatingSystem.IsBrowser()throw-guards that were added inside the leaf classes — those guards make AES correctly throw on browser but do not break the trim linkage.Size impact
Untrimmed
System.Security.Cryptography.dllin the net11 browser-wasm runtime pack is ~670 KB of managed IL (for comparison,System.IO.Compression.dllitself is ~184 KB). The trimmed + Webcil + AOT-native cost that actually ships is smaller than the untrimmed IL but non-trivial: on browser-wasm crypto has no OpenSSL backing, so the managed implementations of AES/HMAC-SHA1/PBKDF2/RNG are what get retained, and the AOT-compiled native contribution todotnet.native.wasmcompounds it. Exact trimmed/AOT delta should be measured with a before/after browser-wasm publish.Suggested fix
Break the linkage on browser-wasm (and any platform where zip encryption is not supported) by placing foldable
OperatingSystem.IsBrowser()guards that throw at the call sites inZipArchiveEntry(.Async).cs(before the crypto leaf types are referenced), so ILLink constant-folds them and removes the encryption branches as unreachable, droppingSystem.Security.Cryptographyfrom the closure.Note this is all-or-nothing: AES is already unsupported on browser, but
ZipCryptoStream(legacy ZipCrypto) is currently unguarded and only usesRandomNumberGenerator.Fill+CryptographicOperations.ZeroMemory(both browser-workable), so it independently keeps crypto linked. To fully remove the dependency, ZipCrypto encryption must also be declared unsupported on browser — a small behavior decision for the area owners, defensible given AES is already unsupported there and ZipCrypto is legacy/weak.Side effect on CI
This regression is also the root cause of the Known Build Error #130540 (
ReferenceNewAssemblyRebuildTest— "Expected changed file: driver-gen.c"): the test relied onSystem.Security.Cryptographybeing absent from the base app's AOT closure. Now that it is always present, the AOT modules table (driver-gen.c) no longer changes on rebuild. Fixing the trim linkage would also resolve that test (though the test is being hardened separately so it can't rot again).Evidence
0174483358e, 2026-07-09 13:35 UTC)/cc @dotnet/area-system-io-compression
Note
This issue was investigated and drafted with the assistance of GitHub Copilot.