Getting Started
Architecture
NServiceBus
Transports
Persistence
Hosting
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Modernization
Samples

FIPS Compliance

Component: NServiceBus
NuGet Package: NServiceBus 8.x
Standard support for version 8.x of NServiceBus has expired. For more information see our Support Policy.

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.

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.Security.Cryptography 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

NServiceBus uses the MD5 hash algorithm to generate deterministic unique identifiers for endpoints, also known as host IDs. MD5 is not FIPS compliant. To run an NServiceBus endpoint under a FIPS policy, override the host identifier using a non-cryptographic hash that is not subject to FIPS enforcement.

A replacement for the MD5-based DeterministicGuid utility can be implemented using XxHash128 from the System.IO.Hashing package, which targets .NET Standard 2.0 and .NET Framework 4.6.2:

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]);
    }
}

Next, set the HostId as part of the endpoint configuration:

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.