8

I am looking for a SHA256 implementation in C# that is FIPS compliant. It turns out that SHA1CryptoServiceProvider works. But why does SHA256CryptoServiceProvider trip the

{"This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms."}

error? Seems like it should just work.

var sha = System.Security.Cryptography.SHA256CryptoServiceProvider.Create();   // not FIPS

In this case I am using .NET 4.5, but the same thing happens in 3.5 and 4.0. I thought SHA256CryptoServiceProvider was the FIPS-compliant alternative to SHA256Managed. SHA256Cng throws the same error.

Update. I think I needed to make a "new SHA256CryptoServiceProvider" instead of using Create()

tofutim
  • 22,664
  • 20
  • 87
  • 148
  • Did that update solve your issue? As far as I can see, there is no `SHA256CryptoServiceProvider.Create()` method? Or do you have the same issue, but no compilation issues anymore? – Maarten Bodewes Jan 24 '14 at 15:58
  • That method definitely exists. I think everything is working now. – tofutim Jan 24 '14 at 19:54
  • 1
    OK, never imagined that such a thing could make a difference. Could you convert your update to an answer (and accept it after a while)? Seems interesting enough for other visitors. – Maarten Bodewes Jan 24 '14 at 21:57
  • Yes. Convert your update to an answer. – FrankO Jul 16 '14 at 17:41

2 Answers2

6

As the original poster suggested in the update, the solution is to actually create a new instance of the SHA256CryptoServiceProvider (or 512). Calling Create will not work:

var csp = new SHA512CryptoServiceProvider();
byte[] hashedBytes = csp.ComputeHash(......);
String hashedText = Convert.ToBase64String(hashedBytes); 
Andy Stevenson
  • 621
  • 6
  • 10
1

There is no SHA256CryptoServiceProvider.Create(), but there is a SHA256.Create() :

On the .NET Framework, this method creates an instance of the SHA256Managed class if FIPS mode is not active; if FIPS mode is active, it creates an instance of the SHA256Cng class.

There is one caveat, however (which maybe was the original problem):

On .NET 4.6.1 and earlier, with FIPS enabled, this picked SHA256Managed, which is not FIPS-compliant.

If you want to target .NET <= 4.6.1, you can use something along the lines of:

public static SHA256 CreateSHA256()
{
    try
    {
        return SHA256.Create();
    }
    catch (TargetInvocationException)
    {
        return SHA256CryptoServiceProvider.Create();
    }
}
gregmac
  • 24,276
  • 10
  • 87
  • 118