Skip to content

[wasm] System.IO.Compression roots System.Security.Cryptography into every trimmed app using ZipArchive (size regression from #122093) #130650

Description

@lewing

Summary

PR #122093 ("Add Zip Archives password support", merged 2026-07-09, commit 0174483358e) added an unconditional ProjectReference 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):

<ProjectReference Include="$(LibrariesProjectRoot)System.Security.Cryptography\src\System.Security.Cryptography.csproj" />

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:

  • Aes.Create()
  • IncrementalHash.CreateHMAC(HashAlgorithmName.SHA1, ...)
  • Rfc2898DeriveBytes.Pbkdf2(...) (PBKDF2)
  • RandomNumberGenerator.Fill(...)
  • CryptographicOperations.ZeroMemory(...)

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).

Evidence

/cc @dotnet/area-system-io-compression

Note

This issue was investigated and drafted with the assistance of GitHub Copilot.

Metadata

Metadata

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions