Skip to content

Compute public-key tokens with a managed SHA-1 - #3780

Merged
siegfriedpammer merged 1 commit into
masterfrom
managed-sha1-pubkey-token
Jun 13, 2026
Merged

Compute public-key tokens with a managed SHA-1#3780
siegfriedpammer merged 1 commit into
masterfrom
managed-sha1-pubkey-token

Conversation

@siegfriedpammer

Copy link
Copy Markdown
Member

On FIPS-mode systems the platform crypto provider refuses to create SHA-1 instances (OpenSSL: error:03000098 invalid digest), so merely displaying a strong-named assembly's identity failed. The public-key token is a non-secret identity hash whose algorithm is fixed by ECMA-335 (last 8 bytes of the SHA-1 of the public key, reversed), so it should not depend on the host crypto policy.

Changes

  • Vendor dotnet/runtime's managed Sha1ForNonSecretPurposes (commit 6e51f762) into ICSharpCode.Decompiler/Util/, license header intact. The only deviations from upstream are a provenance comment and unchecked blocks in Finish/Drain, required because this project compiles with CheckForOverflowUnderflow while SHA-1 relies on wrapping 32-bit arithmetic.
  • Mark the vendored file generated_code = true in .editorconfig so dotnet format keeps it byte-identical to upstream and future syncs diff cleanly.
  • Route both token sites (MetadataExtensions.CalculatePublicKeyToken, AssemblyReferences.GetPublicKeyToken) through it; ICSharpCode.Decompiler no longer references System.Security.Cryptography for metadata reading.
  • Add RotateLeft to the existing BitOperations polyfill (netstandard2.0 has no System.Numerics.BitOperations).

IncrementalHash was considered and rejected: like SHA1.Create(), it resolves the digest through the platform provider, so it fails identically under restrictive crypto policies. Roslyn's token code (CryptographicHashProvider.ComputeSha1) also uses the platform SHA-1, so it offers no precedent for FIPS safety.

Tests

New Sha1ForNonSecretPurposesTests: FIPS-180 vectors through both the one-shot and incremental paths, a cross-check against platform SHA-1 for all input lengths 0-130 (covers every block/padding boundary), Start() reuse, and the ECMA standard public key producing the well-known token b77a5c561934e089.

🤖 Generated with Claude Code

On FIPS-mode systems the platform crypto provider refuses to create
SHA-1 instances (OpenSSL: error:03000098 invalid digest), so merely
displaying a strong-named assembly's identity failed. The public-key
token is a non-secret identity hash whose algorithm is fixed by
ECMA-335, so the two token sites now use dotnet/runtime's managed
Sha1ForNonSecretPurposes, vendored with its license header intact and
shielded from the repo formatter via generated_code in .editorconfig
so future upstream syncs diff cleanly. IncrementalHash was considered
and rejected: like SHA1.Create(), it resolves the digest through the
host crypto policy, and Roslyn's equivalent token code also relies on
the platform SHA-1, so it offers no precedent for FIPS safety.

Assisted-by: Claude:claude-fable-5:Claude Code
@siegfriedpammer
siegfriedpammer added this pull request to the merge queue Jun 13, 2026
Merged via the queue into master with commit 67533d7 Jun 13, 2026
9 checks passed
@siegfriedpammer
siegfriedpammer deleted the managed-sha1-pubkey-token branch June 13, 2026 09:45
@cscgg

cscgg commented Jul 15, 2026

Copy link
Copy Markdown

@christophwille when will this be included in a new release? I'm finding it very hard to run ILSpy on FIPS-enabled systems due to this. Thank you.

@christophwille

Copy link
Copy Markdown
Member

@christophwille when will this be included in a new release? I'm finding it very hard to run ILSpy on FIPS-enabled systems due to this. Thank you.

You can download at any time from the master builds

@cscgg

cscgg commented Jul 15, 2026

Copy link
Copy Markdown

@christophwille Thanks for the quick reply! Totally understand the master builds are available, but for my use case I'm consuming ILSpy as a library in a dotnet microservice, so pulling from CI artifacts isn't really practical... I need a proper NuGet package I can pin a version to and update deliberately. Would it be possible to get this into an official NuGet release sometime soon? Happy to help test if that's useful. Thanks.

@christophwille

Copy link
Copy Markdown
Member

So https://github.com/icsharpcode/ILSpy/pkgs/nuget/ICSharpCode.Decompiler doesn't work for you?

@cscgg

cscgg commented Jul 21, 2026

Copy link
Copy Markdown

@christophwille thanks for sending out v11.0-preview1, seems to be working a treat. cheers

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants