Wednesday 21 October 2015

[Solution] This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.

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

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

 Exception Details: System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.


[InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.]
   System.Security.Cryptography.MD5Cng..ctor() +3211126
   System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(String password, String passwordFormat) +157



Cause
This is an error generated on .Net Framework, and according to Microsoft "Windows Workflow Foundation implements hash algorithms by using Message Digest 5 (MD5). However, MD5 is not compliant to the FIPS algorithm."
If wcf not in application there muste be MD5 Cryptography being used in application.


What is FIPS?

FIPS (Federal Information Processing Standards) are a set of standards that describe document processing, encryption algorithms and other information technology standards for use within non-military government agencies and by government contractors and vendors who work with the agencies.

Know all FIPS compliant Algorithms in C# 

Resolution:
To resolve the customer’s problem, we removed "fipsalgorithmpolicy"=dword:00000001 from [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa].
Here is fixed image of this solution.


or

       
string passwordFormat = "sha1";//use sha1 instead of MD5
return FormsAuthentication
    .HashPasswordForStoringInConfigFile( Convert.ToString( strstring ), passwordFormat );


Another method is to directly edit the registry by setting the following value to 0 (disable) or 1 (enable)
HKLM\System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy
Alternatively you can copy the following lines into a registry script file (.reg) and run it.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
"fipsalgorithmpolicy"=dword:00000001
Note: One thing that I am not certain off is that this option might be available only on Windows XP Professional OSs and not in the basic Windows XP OS. I havent been able to confirm this via documentation - but the option is not available on my home machine (Windows XP), but is available on my work machine (Windows XP Pro).
For Developers:
So what does this mean for developers? If you ever envision your software running on a government computer (especially in the US), you should turn on FIPS compliance checking. This way, your application that uses cryptography algorithms provided by the OS will work on all machines and you wont have to deal with the "Exception has been thrown by the target of an invocation".
For .NET Developers:
FIPS compliance checking (if turned on in the local security policy) I think was introduced starting in version 2.0 of .NET. Unfortunately, the MSDN documentation on FIPS compliance is pretty skimpy and there is no list of the algorithms in the "System.Security.Cryptography" namespace that are FIPS compliant. (Also there is no property that can be checked or an interface or base class that FIPS compliant algorithms implement - which would allow for runtime checking - hint, hint MS).
So here is a quick list that I obtained by using reflection (C# code is below)
FIPS compliant Algorithms:
Hash algorithms
HMACSHA1
MACTripleDES
SHA1CryptoServiceProvider
Symmetric algorithms (use the same key for encryption and decryption)
DESCryptoServiceProvider
TripleDESCryptoServiceProvider
Asymmetric algorithms (use a public key for encryption and a private key for decryption)
DSACryptoServiceProvider
RSACryptoServiceProvider
Algorithms that are not FIPS compliant
HMACMD5
HMACRIPEMD160
HMACSHA256
HMACSHA384
HMACSHA512
MD5CryptoServiceProvider
RC2CryptoServiceProvider
RijndaelManaged
RIPEMD160Managed
SHA1Managed

Seems Most of the time people stuck with SHA256 here is complete details:

SHA256 Class is used to Computes the SHA256 hash for the input data.
The hash size for the SHA256 algorithm is 256 bits.
This is an abstract class. The only implementation of this class is SHA256Managed.
https://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256(v=vs.110).aspx


SHA256Managed Class is used to Computes the SHA256 hash for the input data using the managed library.
The hash size for the SHA256Managed algorithm is 256 bits.
https://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256managed(v=vs.110).aspx

SHA256Managed Constructor ()
Important   If you enable the following security setting either in the Local Security Policy or as part of Group Policy you will get an InvalidOperationException when you attempt to use this constructor:
System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing
https://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256managed.sha256managed(v=vs.110).aspx

SHA256 Hash Algorithm Not FIPS Compliant #571
https://github.com/IdentityServer/IdentityServer3/issues/571



Some Common HashCalculation Methods in C# are


static string _SHA1CryptoServiceProvider(string password)
        {
            System.Security.Cryptography.SHA1CryptoServiceProvider crypt = new System.Security.Cryptography.SHA1CryptoServiceProvider();
            System.Text.StringBuilder hash = new System.Text.StringBuilder();
            byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(password), 0, Encoding.UTF8.GetByteCount(password));
            foreach (byte theByte in crypto)
            {
                hash.Append(theByte.ToString("x2"));
            }
            return hash.ToString();
        }

        static string _SHA256CryptoServiceProvider(string password)
        {
            System.Security.Cryptography.SHA256CryptoServiceProvider crypt = new System.Security.Cryptography.SHA256CryptoServiceProvider();
            System.Text.StringBuilder hash = new System.Text.StringBuilder();
            byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(password), 0, Encoding.UTF8.GetByteCount(password));
            foreach (byte theByte in crypto)
            {
                hash.Append(theByte.ToString("x2"));
            }
            return hash.ToString();
        }

        static string _SHA256Managed(string str)
        {
            SHA256Managed crypt = new SHA256Managed();
            string hash = String.Empty;
            byte[] crypto = crypt.ComputeHash(Encoding.ASCII.GetBytes(str), 0, Encoding.ASCII.GetByteCount(str));
            foreach (byte theByte in crypto)
            {
                hash += theByte.ToString("x2");
            }
            return hash;
        }

        public string _HMACSHA256(string data)
        {
            string hash = String.Empty;
            byte[] mbyte = Encoding.ASCII.GetBytes(data);
            HMACSHA256 hmac = new HMACSHA256();
            byte[] hmsg = hmac.ComputeHash(mbyte, 0, Encoding.ASCII.GetByteCount(data));
            foreach (byte theByte in hmsg)
            {
                hash += theByte.ToString("x2");
            }
            return hash;

        }