19

Right now the only way I can get the RijndaelManaged algorithm to work on a computer with the Local Security Setting for FIPS turned on, is to disable it. It is a government computer, so I'm not sure how that will fly. I've seen posts on the msdn blog sites that say they are working on an AES FIPS compliant version, but I cant seem to find out anything more. Does anyone know when this might happen?

SwDevMan81
  • 45,922
  • 20
  • 140
  • 177
  • Related question: http://stackoverflow.com/questions/371534/asp-net-2-0-rijndaelmanaged-encryption-algorithm-vs-fips – Jeff Moser Jun 02 '09 at 13:34
  • I did read that you could put something like this in a configuration file: But that didnt seem to work, the application was still closed. – SwDevMan81 Jun 02 '09 at 14:14
  • 1
    Ok, I got the enforceFIPSPolicy flag to work, turns out I needed to add it below all the tags in the configuration section of the exe.config file, doesnt seem to work at the top above the configSections and userSettings. Hope that helps others. – SwDevMan81 Jun 02 '09 at 17:18
  • I think it'd still be valid to figure out why your AesCryptoServiceProvider code didn't work rather than work around this with a config file. I think you'll have better long term results. – Jeff Moser Jun 03 '09 at 21:58
  • My site had to get a waver for FIPS compliance in .net. – Jeff Walker Feb 25 '10 at 19:11
  • Where did get the waiver? – SwDevMan81 Feb 25 '10 at 23:16
  • NETWARCOM? This is the Navy command that hands down the security edicts. – Jeff Walker Mar 01 '10 at 17:14

3 Answers3

18

I never realized this before this question, but you're right. The constructor has this:

public RijndaelManaged()
{
    if (Utils.FipsAlgorithmPolicy == 1)
    {
        throw new InvalidOperationException(Environment.GetResourceString("Cryptography_NonCompliantFIPSAlgorithm"));
    }
}

System.Security.Cryptography.AesManaged has something similar:

public AesManaged()
{
    if (CoreCryptoConfig.EnforceFipsAlgorithms)
    {
        throw new InvalidOperationException(SR.GetString("Cryptography_NonCompliantFIPSAlgorithm"));
    }
    this.m_rijndael = new RijndaelManaged();
    this.m_rijndael.BlockSize = this.BlockSize;
    this.m_rijndael.KeySize = this.KeySize;
}

Have you tried System.Security.Cryptography.AesCryptoServiceProvider? It should work since it's using the CAPI based FIPS AES implementation built into Windows.

This question on Microsoft's .NET Base Class Library forum discusses which algorithms are FIPS compliant and has good links.

It appears that Microsoft is making a consistent effort to obey the setting of HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy on pre-Vista machines and use of the BCryptGetFipsAlgorithmMode API for post-Vista.

I assume there is non-trivial effort involved in certifying an implementation as FIPS compliant, that is why Microsoft probably doesn't want to repeat the process and only offers the AesCryptoServiceProvider for customers that absolutely need this requirement.

This MSDN blog post has a comment that makes it clearer:

The easy way to figure out if an algorithm is compliant or not is to look at the suffix. None of the *Managed types are FIPS certified. The *CryptoServiceProvider and *Cng types however, may well be FIPS certified. If they implement an algorithm that FIPS allows, and are using the default Microsoft providers, then they will be.

For instance, SHA256Managed is not (because it is *Managed). SHA256CryptoServiceProvider and SHA256Cng are.
MD5CryptoServiceProvider is not (because MD5 is not a FIPS algorithm).

Jeff Moser
  • 18,820
  • 6
  • 58
  • 83
  • We did try the AesCryptoServiceProvider first, but we couldn't get the desired encryption/decryption results and I dont think it is supported in the compact framework. Everything with the RijndealManaged seemed ok, until we ran into this problem – SwDevMan81 Jun 02 '09 at 12:21
  • By "results", do you mean performance? It looks like Microsoft doesn't want to go through an implementation validation process for something beyond their CAPI for the current time. Microsoft clearly went out of their way to (probably) comply with Federal customers who wanted a single policy bit they could set to prohibit non-FIPS solutions. You could use a library like BouncyCastle ( http://www.bouncycastle.org/csharp/index.html ) that ignores this bit if you simply wanted to use a managed FIPS implementation. – Jeff Moser Jun 02 '09 at 13:16
  • (Updated answer with additional info) – Jeff Moser Jun 02 '09 at 13:21
  • 1
    By results, I mean we tried the AesCryptoServiceProvider and RijndealManaged with the same cipher mode (CFB), padding (None), init vector and keys and they produced different encrypted results. – SwDevMan81 Jun 02 '09 at 13:54
  • Were your key bytes and block sizes identical? They should produce identical results. Can you post a brief snippet of what you tried into a new question with a title like "Why are RijndaelManaged and AesCryptoServiceProvider returning different results?" and then link to that from here and I'll try to check it out. – Jeff Moser Jun 02 '09 at 14:59
  • Yeah, I'll have to do it later, but I can post it. – SwDevMan81 Jun 02 '09 at 15:08
  • 1
    http://stackoverflow.com/questions/957388/why-are-rijndaelmanaged-and-aescryptoserviceprovider-returning-different-results – SwDevMan81 Jun 05 '09 at 18:34
  • What would be the correct code for the Utils.FipsAlgorithmPolicy function? Thank you! – Luke Oct 05 '09 at 12:43
  • Luke: The "AesCryptoServiceProvider" uses the Crypto API (CAPI) which is FIPS compliant: AesCryptoServiceProvider. The Utils.FipsAlgorithmPolicy on Vista and later, calls BCryptGetFipsAlgorithmMode: http://msdn.microsoft.com/en-us/library/aa375460%28VS.85%29.aspx on earlier OS's, a check to "FIPSAlgorithmPolicy" value under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa is done. All this said, if at all possible, try to refactor your design to use TLS/SSL or some high level crypto instead of calling this class directly. – Jeff Moser Oct 06 '09 at 13:46
  • I wrote much more about this in a comment to my Stick Figure Guide to AES: http://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html?showComment=1254448126873#c7933132611242458392 – Jeff Moser Oct 06 '09 at 13:47
7

This problem is much more complex than most of those responding understand. Here is the true reason why most of people's answers just won't work (I just spent a nearly 48-hour marathon session trying to understand and fix this problem):

  1. C# Under Windows has basically 3 encryption providers that "support" AES: RijndaelManaged, AesManaged, AesCryptoServiceProvider.
  2. RijndaelManaged implements the full Rijnadael Algorithm (All Options) and so it is a super-set of AES capabilities; however, it is not certified FIPS compliant (because it is capable of doing things not in the FIPS-approved AES specification, like having block size other than 128 bits)
  3. AesManaged is nothing more than a decorator/wrapper over RijndaelManaged that restrict it to a block-size of 128 bits, but, because RijndaelManaged is not FIPS approved, neither is AesManaged
  4. AesCryptoServiceProvider is a C# wrapper over the C-library on Windows for AES that IS FIPS approved; however, in CFB Mode, it only supports 8|16|24|32|40|48|56|64 bits for the FeedbackSize (I can find no documentation that says that FIPS is restricted thusly, so, it's questionable how AesCryptoServiceProvider passsed the FIPS certification - probably somebody played midnight golf with someone else to have it pushed through the certification)
  5. If FIPS mode is turned on on Windows, then RijndaelManaged (and thereby AesManaged) will throw and exception saying they are not FIPS compliant when you attempt to instantiate them.
  6. Some things require AES-128 with CFB of 128-bits FeedbackSize (e.g. SNMPv3 AES according the the RFC).

So, if you are in an environment where the following is true:

  1. You need AES-128 with CFB-128 (SNMPv3 for example)
  2. You need to do the Crypto from C# without using Non-Microsoft Libs
  3. You need to have FIPS mode turned on on the OS (Gov't requirements for example)

Then, your ONLY option (or at least the only I could find after extensive searching and much wailing and gnashing of teeth) is to use RijndaelManaged AND use the "<configuration> <runtime> <enforceFIPSPolicy enabled="false"/> <runtime> </configuration>" in the Application.exe.config to turn-off FIPS forced compliance for that particular application.

What a nightmare! I hope this answer helps the next unfortunate soul to run into this problem.

Keywords: Cisco IOS SNMPv3 FIPS AES 128 CFB 128 AesCryptoServiceProvider Rijndael

G Butler
  • 99
  • 1
  • 2
1

The unmanaged AesCryptoServiceProvider is certified if the OS itself is certified as it calls the OS. And it will be a darned site quicker as well, at the cost of cross platform compatibility.

blowdart
  • 52,422
  • 11
  • 102
  • 145