I am using .net 3.5 and I'm trying to make my app FIPS compliant.I don't use any of the non FIPS algorithms but I still get this error when I run it on the production server.
This implementation is not the part of the Windows platform FIPS validated cryptographic algorithms.
Here is the List of algorithms that I have checked and I am sure that I haven't used them.
HMACMD5
HMACRIPEMD160
HMACSHA256
HMACSHA384
HMACSHA512
MD5CryptoServiceProvider
RC2CryptoServiceProvider
RijndaelManaged
RIPEMD160Managed
SHA1Managed
How can I find exactly where the problem is or any other ideas?
When you say "FIPS compliant", I assume you want to enforce FIPS 140 compliance in Windows and .Net cryptographic libraries mode by changing the Local Security Policy settings.
The challenge with FIPS 140 compliance (usually level 1 of the latest version of the standard, FIPS 140-2) using this mechanism, as you have discovered, is that it prevents the instantiation of non-FIPS 140 compliant algorithms, even if they are not used for a security-related purpose.
Presumably you have checked your code for any references to non-compliant algorithms using a tool like ildasm or Reflector. Otherwise, debug your code and look at the stack trace of the thrown InvalidOperationException to see where the problem lies.
One easy way to accomplish this is use the generic classes and avoid calling constructors directly. For example, if you want to use Advanced Encryption Standard (AES), instead of:
// Use the faster .Net implementation of AES. Not FIPS 140 compliant.
using (AesManaged aesManaged = new AesManaged())
{
// Do something
}
use:
// Let .Net workout which implementation of AES to use. Will use
// a FIPS compliant implementation if FIPS is turned on.
using (Aes aes = Aes.Create())
{
// Do something
}
Beyond your code, check third party libraries you use. You can use similar tools to the above to check any references from their code. If you have checked your code thoroughly, this is likely where the problem lies. Note that disassembling third party code could be a breach of copyright or license agreements.
Also check your SSL configuration. For example, the digital certificate used for SSL cannot used MD5. You also must use TLS 1.0 or later.
However, forcing Windows FIPS 140 compliance is doing it the hard way. Most customers, including the US government, do not require only FIPS compliant algorithms (or technically, implementations of these algorithms) to be used. For example, they are perfectly happy for you to use MD5 to create a hash key of a string.
Instead, customers want anything your product protects using cryptography to be protected by FIPS 140 complaint implementations of approved algorithms. In other words:
Identify each thing your product should protect
Protect them using FIPS 140 compliant libraries
Use tooling (e.g. static analysis), code review and/or third party audit to demonstrate enforcement.
Also note that turning on FIPS 140 mode does not necessarily make Windows or your product more secure. Security is much more complicated than choosing one cryptographic algorithm over another (or, specifically, a particular implementation of an algorithm over another implementation). Microsoft no longer recommends this be turned on by default.
Related
I am developing a windows service from where i cannot read registry. So i am looking forward for code solution to check whether machine is FIPS compliant or not.
.
if you could see the highlighted entry in the image. That particular entry i have to read from the code.
How To Read Security Options "System cryptography: Use FIPS compliant algorithms for encryption, hasing and signing" Programmatically. Where in RSOP I should query?
A dirty workaround to detect if FIPS algorithms are enforced may be to use one that is known to be non FIPS complaint like RijndaelManaged.
If enforcement is enabled it will throw an exception explicitly saying it's because of FIPS compliancy.
Dirty, but it may solve your problem...
In my application a CRC value is computed for a file by using the System.Security.Cryptography.MD5 (C#). It is used as a compact digital fingerprint.
The MD5 class is declared non-FIPS compliant and "everything" works fine if the following Windows Local Policy is disabled:
"System Cryptography: Use FIPS compliant algorithms for encryption, hashing and signing".
Now, I need to enable the above System Policy, but the MD5 class fails when called..
Is there a way to compute the CRC value exactly as if you are using the System.Security.Cryptography.MD5?
Thanks in advance, regards
As Damien_The_Unbeliever mention above, your requirements are incompatible. But a slightly more detailed answer would be "yes and no".
No: MD5 should not be used any more as there are known collisions. It is broken for pretty much all cryptographic purposes. If those fingerprints are used in any security relevant context then you're well advised to change to a secure hash function. SHA2 and SHA3 are secure and FIPS certified. Switching an entire application to a different hash function may cause you some pain now but the alternative is more pain later.
Yes: It is possible - you could reimplement MD5 yourself or use a library that does not check for the Windows policy. All you'd have to do is ensure a correct data format. However, I would strongly advise against this option. MD5 is broken.
Since you've stated that you have to enable the policy for FIPS compliant cryptography, I would assume that this is either a customer or sales requirement which leaves you with no choice but to switch to SHA2 or SHA3.
I need to port MACTripleDes functionality to another programming language and want to know what it really does.
So I have data and a keypharse given.
Is it right, to just TripleDes the data with an IV=0 and the keyphrase, and then take the last 8 byte as the MAC ?
Ciao
Ephraim
DO NOT WRITE YOUR OWN CRYPTOGRAPHIC FUNCTIONS! Not even a direct port of an existing function.
If your language has any maturity, it will have an open source implementation that you can use. If it does not, DO NOT PORT ONE! Find one in another language and write a wrapper for it that you can call (like the C# implementation that you want to port).
Any existing open source implementation will be tested and verified for correctness by people who know far more about cryptography than me, you and over 99% of the global developer population.
If you really cannot find an open source implementation, write a simple .exe using C# that calls the C# implementation and returns the result. Not including setup and boilerplate, that's basically one line of code.
Again, if you write your own implementation, you will inevitably fail to account for some edge case or not understand the algorithm enough, resulting in a dangerous piece of code with exploitable flaws. Unless you are one of the original developers of 3DES or have many years of experience developing currently used encryption standards, you simply do not have the technical skill to port an implementation.
Again, if you write your own implementation, something goes wrong and your data gets leaked, you can and will be held personally accountable. Linkedin was recently sued for $ 5 million because they didn't implement proper security. This is something that can break your career.
DO NOT MAKE THE SAME MISTAKE AS LINKEDIN!
Apparently, the MACTripleDES class implements CBC-MAC using Triple DES as the underlying block cipher. If you have access to a crypto library that implements CBC-MAC and Triple DES (and lets you use the latter as the block cipher in the former, as any generic CBC-MAC implementation should), you should be able to combine them to obtain an equivalent MAC.
Alternatively, if your crypto library does not directly implement CBC-MAC, but does implement CBC mode encryption, you can indeed implement CBC-MAC yourself by encrypting the message in CBC mode, using an all-zero IV, and taking the last block of the resulting ciphertext as the MAC value. (This is simply the definition of CBC-MAC.) It is also not particularly difficult or tricky to implement CBC mode (or CBC-MAC) yourself, using just the raw block cipher. But really, any decent crypto library should already provide CBC-MAC, or at least CBC mode encryption, built in.
What you should not try is implementing Triple DES, or any other block cipher, yourself! It's very hard to implement low-level crypto algorithms like Triple DES securely, since you have to pay attention to things like side-channel attacks, and any such implementation should be thoroughly tested and scrutinized by professional cryptographers before being used for anything serious.
(One specific exception here is that, if you only have access to the plain DES block cipher, you may reasonably safely implement Triple DES on top of that. This is because Triple DES is not actually a separate low-level cipher, but simply a method of expanding the keyspace of DES, at the expense of performance, by encrypting each block several times with independent keys. But again, any decent crypto library written in the last 20 years should support Triple DES if it supports DES at all.)
Of course, even when only implementing high-level crypto algorithms like CBC-MAC, it's still possible to make mistakes, and such mistakes can have security consequences. But at this level, the difficulty and the risk are not significantly greater than those inherent in simply using crypto (and therefore, by implication, working with security-critical data like encryption keys) in the first place. Even so, it's always a good idea to have someone (or, preferably, several someones) with crypto experience review your code before it's deployed. This holds even if you're a crypto expert yourself; anybody can make mistakes, and the more eyeballs you can get on your code, the more likely it is that any mistakes are found before someone exploits them.
Finally, note that, if you don't specifically need compatibility with Microsoft's MACTripleDES class, there are better choices for MAC algorithms than CBC-MAC (such as CMAC), and better choices for ciphers than Triple DES (such as AES). The specific combination of AES and CMAC is even standardized in RFC 4493, which provides detailed implementation instructions and test vectors to verify correctness.
In particular, plain CBC-MAC is not secure for variable-length messages, if the message length is not authenticated. While there are ways to fix this vulnerability, e.g. by prepending the length to the message before computing the MAC, it's generally preferable to use an algorithm that is secure "out of the box", like CMAC.
(Also, since you mention a "keyphrase" in your question, I hope you're actually feeding it through a proper key derivation function before using it as a key for Triple DES (or any other block cipher). In particular, if the keyphrase is user-supplied, and thus likely to have low entropy, you really should be using a key-stretching KDF like PBKDF2, scrypt or Argon2.)
I am creating a keyed SHA256 hash using HMACSHA256 with the following code:
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey);
byte[] hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
string hashResult = string.Empty;
for (int i = 0; i < hash.Length; i++)
{
hashResult += hash[i].ToString("x2"); // hex format
}
This is working just fine, however, it fails in a FIPS enabled environment because HMACSHA256 uses an underlying SHA256Managed implementation which is itself not FIPS compliant.
Searching through MSDN documentation I find that the only SHA256 implementation of KeyedHashAlgorithm is HMACSHA256.
I am required to sign web service requests with a keyed SHA256 hash (so I can't change the hash type), and I must be able to run in a FIPS enabled environment.
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.
I know this is old but it looks like Microsoft addressed this issue. I'm running .NET 4.5.1 on Windows 8. I can't speak to what version of the BCL this was fixed or OS.
this.m_hash1 = HMAC.GetHashAlgorithmWithFipsFallback((Func<HashAlgorithm>) (() => (HashAlgorithm) new SHA256Managed()), (Func<HashAlgorithm>) (() => HashAlgorithm.Create("System.Security.Cryptography.SHA256CryptoServiceProvider")));
No, there is not. Here is a list of ones that are (scroll down to FIPS.sys Algorithms section).
A work around I've used int he past is here, but I'm not sure if that will work for web services. This solution could work.
Officially you may be out of luck, but it should be relatively easy to build a HMAC_SHA256 out of SHA-256. Just take a look at the Wikipedia page to see how easy this is.
Note that it may be the case that HMAC was not approved in FIPS mode because it is vulnerable to side channel attacks. In that case you should make sure that there is some protection against side channel attacks.
It is a bit dangerous to build your own crypto algorithms out of cryptographic primitives. If you yourself will try and claim FIPS level security then this may become an issue. But for most users it is enough if you say that you only use NIST compliant algorithms. It is up to you how far you are willing to go down this line...
I'm trying to understand some C#-code, I have been handed, which deals with cryptography, and specifically uses PasswordDeriveBytes from System.Security.Cryptography.
In the .NET docs , it says that PasswordDeriveBytes uses "an extension of the PBKDF1 algorithm" which is later in the document specified as "the PKCS#5 v2.0 standard", which is PBKDF2 (as far as I can tell). Everywhere on the net I've found (including here on Stack Exchange), though, everyone says "use Rfc2898DeriveBytes, cause Password* is deprecated and uses PBKDF1". But the only difference in the docs at msdn.microsoft.com seems to be that the Rfc*-version specifically mentions PBKDF2, where Password* says "extension of PBKDF1" and "PKCS#5 v 2.0".
So, can anyone tell me what the difference is between the two classes (if any) and why I should use one rather than the other for PBKDF2 password key derivation?
Now, other code, that deals with the same data, explicitly uses PBKDF2, and works, so that would suggest that indeed PasswordDeriveBytes also uses PBKDF2, or that PBKDF2 is simply compatible with PBKDF1 under certain circumstances, but I want to know for sure that it's not some side effect of some random thing, and that things just magically works (and eventually probably will magically and spectacularly break) without anyone really understanding why.
If you instantiate PasswordDeriveBytes and make a single call to the GetBytes method passing a value which is smaller than the output size of the underlying digest algorithm then you get back a value from the PBKDF1 algorithm.
If you make two calls to GetBytes for the same object you may encounter a counting bug in the implementation.
PBKDF1 is only described to output up to the size of the hash algorithm (e.g. 20 bytes for SHA-1), but the PasswordDeriveBytes class has made up a formula to support up to 1000 times the hash output size. So a large value produced by this class may not be easily attainable in another platform.
If you instantiate Rfc2898DeriveBytes you get a streaming implementation of the PBKDF2 algorithm. The most obvious difference of PBKDF2 over PBKDF1 is that PBKDF2 allows the generation of an arbitrary amount of data (the limit is (2^32-1)*hashOutputSize; or for SHA-1 85,899,345,900 bytes). PBKDF2 also uses a more complex construction (in particular, HMAC over direct digest) to make recovering the input password from an output value more difficult.
The "streaming" in the implementation is that the concatenation of GetBytes(5) and GetBytes(3) is the same as GetBytes(8). Unlike in PasswordDeriveBytes, this works correctly in Rfc2898DeriveBytes.
PBKDF1 was originally created to generate DES keys, published in PKCS #5 v1.5 in 1993.
PBKDF2 was published in PKCS #5 v2.0 (which was republished as RFC2898) in 1999. A slide deck which should be found at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-5v2/pkcs5v2-0.pdf (but seems to be having issues so ftp://ftp.dfn-cert.de/pub/pca/docs/PKCS/ftp.rsa.com/99workshop/pkcs5_v2.0.ppt may hve to do) further summarizes differences. (The slide deck was written by RSA Security, the creators of PBKDF1 and PBKDF2, and they are the people who recommend PBKDF2 over PBKDF1).
I think a great answer to this would be found here:
C# PasswordDeriveBytes Confusion
But to sumup:
Microsoft's implementation of original PKCS#5 (aka PBKDF1) include insecure extensions to provide more bytes than the hash function can provide (see bug reports here and here).
Even if it was not buggy you should avoid undocumented, proprietary extensions to standards (or you might never be able to decrypt your data in the future - at least not outside Windows.)
I strongly suggest you to use the newer Rfc2898DeriveBytes which implements PBKDF2 (PKCS#5 v2) which is available since .NET 2.0.
Here's a blog post detailing the differences:
http://blogs.msdn.com/b/shawnfa/archive/2004/04/14/generating-a-key-from-a-password.aspx
PBKDF2 can be used to generate keys of any length, which is very useful for password-based encryption (it can generate any key length as required by the symmetric cipher) but means less for secure password storage. It also applies the salt using HMAC instead of concatenation like PBKDF1, which has better security properties in cases of weak salts.
PKCS#5 v2.0 defines both PBKDF1 and PBKDF2, the former for reasons of backwards compatibility and also recommends you use PBKDF2 for new applications. I've no idea why the latter is better than the former, but the two .NET classes do seem to use different but interoperable algorithms. (Possibly because only the resulting key is being exchanged, not the inputs + KDF.)