Compute public-key tokens with a managed SHA-1 - #3780
Conversation
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
|
@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 |
|
@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. |
|
So https://github.com/icsharpcode/ILSpy/pkgs/nuget/ICSharpCode.Decompiler doesn't work for you? |
|
@christophwille thanks for sending out v11.0-preview1, seems to be working a treat. cheers |
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
Sha1ForNonSecretPurposes(commit6e51f762) intoICSharpCode.Decompiler/Util/, license header intact. The only deviations from upstream are a provenance comment anduncheckedblocks inFinish/Drain, required because this project compiles withCheckForOverflowUnderflowwhile SHA-1 relies on wrapping 32-bit arithmetic.generated_code = truein.editorconfigsodotnet formatkeeps it byte-identical to upstream and future syncs diff cleanly.MetadataExtensions.CalculatePublicKeyToken,AssemblyReferences.GetPublicKeyToken) through it;ICSharpCode.Decompilerno longer referencesSystem.Security.Cryptographyfor metadata reading.RotateLeftto the existingBitOperationspolyfill (netstandard2.0 has noSystem.Numerics.BitOperations).IncrementalHashwas considered and rejected: likeSHA1.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 tokenb77a5c561934e089.🤖 Generated with Claude Code