Search code examples
c#visual-studiobouncycastlefips

BouncyCastle version conflict FIPS C#


I'm trying to work with FIPS in a CMAC function but I'm running into version conflicts. I have the regular BouncyCastle.Cryptography v2.0.0.0 referenced and bc-fips-1.0.2.dll V1.0.2 reference in Visual Studio 2022, .NET framework 4.8, C#. The bc-fips-1.0.2 is reference because it has "BouncyCastle.Crypto.Fips".

There are essentially two conflicts one with 'SecureRandom' and the other 'CryptoServicesRegistrar.CreateService'.

Error: 'CryptoServicesRegistrar' exists in both 'BouncyCastle.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=072edcf4a5328938' and 'bc-fips-1.0.2, Version=1.0.2.0

Anyone know a workaround or fix for this?

I think you for your assistance in advance.


Solution

  • You stated that you are using both NuGet package BouncyCastle.Cryptography. If one clicks on Project Website, one is taken to BouncyCastle.org which is where one finds bc-fips-1.0.2.dll - information about FIPS (Federal Information Processing Standards) can be found here. While this doesn't necessarily mean that they both use the same namespace, the error message indicates that they do.

    The type 'CryptoServicesRegistrar' exists in both 'BouncyCastle.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=072edcf4a5328938' and 'bc-fips-1.0.2, Version=1.0.2.0, Culture=neutral, PublicKeyToken=null'

    If using Visual Studio, another way one can see the namespaces is to use Object Browser.

    • Click View
    • Select Solution Explorer
    • In Solution Explorer, expand References
    • Right-click bc-fips-1.0.2 and select View in Object Browser
    • Expand bc-fips-1.0.2
    • Expand Org.BouncyCastle.Crypto
    • Select CryptoServiceRegistrar

    While the Object Browser is open:

    • Expand BouncyCastle.Cryptography
    • Expand Org.BouncyCastle.Crypto
    • Select CryptoServiceRegistrar

    This issue is described in this post.

    One possibility is to create two class libraries that use unique namespaces - one class library that contains your methods that use the FIPS compliant version (ie: bc-fips-1.0.2.dll) and a different class library that contains your methods that use the non-FIPS compliant version (ie: BouncyCastle.Cryptography).

    A more desirable option may be to use an alias in the .csproj file as described in this post.

    Note: Ensure that you've configured NuGet Package Manager to use PackageReference in Visual Studio (before adding NuGet package(s)):

    • In Visual Studio menu, click Tools
    • Select Options...
    • Expand NuGet Package Manager
    • Select General
    • Under Package Management, for Default package management format, select PackageReference.
    • Click OK

    • Download/install the NuGet package for BouncyCastle.Cryptography.

    • Download bc-fips.dll from here.

    • Add project reference to bc-fips.dll (Project => Add Reference... => Browse => click browse button...)

    • Either unload your project or close Visual Studio.

    • Modify your project file (.csproj). If you've unloaded your project in Visual Studio, in Solution Explorer, double-click <project name>. If you've closed Visual Studio, then open the .csproj file using Notepad.

      Change from:

      <PackageReference Include="BouncyCastle.Cryptography" >
      

      To:

      <PackageReference Include="BouncyCastle.Cryptography" Aliases="NonFips">
      

      Note: Aliases is only available for NuGet packages. See PackageReference Aliases for more information. Change NonFips to whatever name you like.

    • Either reload your project or open your project again in Visual Studio.

    • Before any using directives add the following:

      extern alias NonFips;
      
    • Build/rebuild your project.

    • When using methods from the non-FIPS compliant version (ie: BouncyCastle.Cryptography) ensure that you use the alias (ie: NonFips or whatever you've named the alias) along with the fully-qualified namespace for the method such as:

      NonFips.Org.BouncyCastle.Crypto.CryptoServicesRegistrar.GetSecureRandom();
      

    Additional Resources: