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()
To be FIPS compliant means an organization adheres to the Federal Information Processing Standards (FIPS) in order to act in accordance with the Federal Information Security Management Act of 2002 (FISMA) and the Federal Information Security Modernization Act of 2014 (FISMA2014).
SHA-1, SHA-256 and SHA-512 are all FIPS Approved secure hash algorithms and the HMAC function based on them are thus FIPS Approved HMAC functions. Using a compliante implementation — the official term is “validated”.
Googling shows that both SHA256CryptoServiceProvider and SHA256Cng are FIPS compliant ways to create SHA256 hashes, but neither seem to support the creation of keyed hashes.
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);
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With