The Federal Information Processing Standards or FIPS are standards developed by the United States government for computer systems that set requirements for, among other things, cryptography.
Microsoft no longer recommends enabling FIPS unless it is required by government regulations.
FIPS policy enforcement only exists on .NET Framework.
The Particular Software Platform is not FIPS compatible, and no testing is done to ensure components will work properly on FIPS-enabled hardware. The platform currently uses System. classes only for hashing, and not for data security purposes.
There are workarounds that allow running NServiceBus and the Particular Service Platform on the .NET Framework on servers with FIPS enforcement enabled, but these workarounds are also not tested or verified in any way.
NServiceBus
Starting in version 10.2, NServiceBus uses a non-cryptographic hash algorithm (XxHash128) to generate deterministic unique identifiers for endpoints, also known as host identifiers (HostIds). Because XxHash128 is not a cryptographic algorithm, FIPS policy enforcement does not block host identifier generation; the host ID workaround described below is no longer needed.
Migrating from MD5 to XxHash128 host identifiers
The XxHash128-based algorithm produces different host identifiers than the legacy MD5-based algorithm. In version 10.2, the legacy MD5 algorithm remains the default, in order to avoid duplicate endpoint entries in the ServicePulse Heartbeats view after upgrading.
To opt into the new XxHash128-based host identifier, set the following AppContext switch before endpoint startup:
AppContext.SetSwitch("NServiceBus.Core.Hosting.UseV2DeterministicGuid", true);
Or via environment variable (.NET 9+):
DOTNET_NServiceBus_Core_Hosting_UseV2DeterministicGuid=true
Or via MSBuild in the project file:
<ItemGroup>
<RuntimeHostConfigurationOption Include="NServiceBus.Core.Hosting.UseV2DeterministicGuid" Value="true" />
</ItemGroup>
Changing the host identifier algorithm changes the host ID that identifies an endpoint in ServicePulse and ServiceControl. Only enable this switch after coordinating with operations teams to ensure monitoring continuity. Endpoints that change their host identifier will appear as new entries in ServicePulse until stale instances are removed from the monitoring view.
In version 11, the XxHash128 algorithm will become the default, and the legacy MD5 algorithm will require explicit opt-out. In version 12, the legacy MD5 algorithm will be removed entirely.
Manual host identifier override (legacy approach)
Before version 10.2, the only workaround for FIPS-enabled systems was to override the host identifier using a non-cryptographic hash that is not subject to FIPS enforcement, such as XxHash128 from the System. package, which targets .NET Standard 2.0 and .NET Framework 4.6.2. This is no longer needed now that NServiceBus uses XxHash128 internally.
using System;
using System.IO.Hashing;
using System.Text;
static class XxHash128DeterministicGuid
{
public static Guid Create(params string[] values)
{
var encoding = Encoding.UTF8;
var hash = new XxHash128();
foreach (var value in values)
{
var bytes = encoding.GetBytes(value);
var lengthPrefix = BitConverter.GetBytes(bytes.Length);
hash.Append(lengthPrefix);
hash.Append(bytes);
}
var hashBytes = hash.GetCurrentHash();
// UUID version 8
hashBytes[6] = (byte)((hashBytes[6] & 0x0F) | 0x80);
// RFC 4122 / RFC 9562 variant
hashBytes[8] = (byte)((hashBytes[8] & 0x3F) | 0x80);
// XxHash128 outputs big-endian bytes but Guid(byte[]) expects little-endian on .NET Framework.
// Swap the first three groups to match the Guid binary layout.
SwapBytes(hashBytes, 0, 3);
SwapBytes(hashBytes, 1, 2);
SwapBytes(hashBytes, 4, 5);
SwapBytes(hashBytes, 6, 7);
return new Guid(hashBytes);
}
static void SwapBytes(byte[] bytes, int a, int b)
{
(bytes[a], bytes[b]) = (bytes[b], bytes[a]);
}
}
endpointConfiguration.UniquelyIdentifyRunningInstance()
.UsingNames(
instanceName: "endpointName",
hostName: Environment.MachineName);
// or
var hostId = CreateMyUniqueIdThatIsTheSameAcrossRestarts();
endpointConfiguration.UniquelyIdentifyRunningInstance()
.UsingCustomIdentifier(hostId);
Component libraries
The following packages use MD5 and cannot be used with FIPS enforcement enabled:
- NServiceBus.RavenDB - Uses MD5 to create shortened keys for subscriptions and saga lookup properties.
- NServiceBus.Gateway - Uses MD5 to ensure integrity of received data.
- NServiceBus.Distributor.Msmq: Uses MD5 to shorten long queue names.
Disable enforcement of FIPS
ServiceControl and ServicePulse also use MD5 internally and will require disabling FIPS enforcement to run properly. As these tools do not execute user code and can be audited as 100% open source, it is sometimes possible to obtain a waiver to run these tools with a configuration flag that instructs the .NET Framework to skip enforcement of FIPS even when configured to do so at the server level with group policy.
FIPS enforcement can be disabled by setting the runtime setting enforceFIPSPolicy to false in the application's app.config or web.config. See the MSDN article on how to change this setting.