ObjectId initialization error when FIPS compliant algorithm policy is enabled

260 views
Skip to first unread message

DaveC

unread,
Sep 14, 2012, 10:01:37 PM9/14/12
to mongod...@googlegroups.com
When using the MongoDB driver from a Windows system with FIPS compliance enabled (see http://support.microsoft.com/kb/811833), I get an error whenever creating an ObjectId, specifically on the ObjectId.GetMachineHash method and it's use of MD5 as shown in the stack trace below. This goes along with the issue I opened a few days ago regarding the use of MD5 in authentication, which the only workaround at the moment is to disable authentication.

After checking the source, I see it creates an MD5 hash of the host name, then grabs the first three bytes of that hash.  Is there any reason this needs to use MD5?  Can that be replaced with something like this?

var alg = System.Security.Cryptography.HMACSHA256.Create();
var hash = alg.ComputeHash(Encoding.UTF8.GetBytes(Environment.MachineName));
return (hash[0] << 16) + (hash[1] << 8) + hash[2];

HMACSHA256 would be preferred, but SHA1CryptoServiceProvider is also FIPS compliant, so that would work as well. I've verified that both of those work on a system with FIPS compliance enabled.

Here is the stack trace for your reference.

  InnerException: System.Reflection.TargetInvocationException
       Message=Exception has been thrown by the target of an invocation.
       Source=mscorlib
       StackTrace:
            at System.RuntimeMethodHandle._InvokeConstructor(IRuntimeMethodInfo method, Object[] args, SignatureStruct& signature, RuntimeType declaringType)
            at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
            at System.Security.Cryptography.CryptoConfig.CreateFromName(String name, Object[] args)
            at System.Security.Cryptography.MD5.Create(String algName)
            at MongoDB.Bson.ObjectId.GetMachineHash() in C:\work\10gen\mongodb\mongo-csharp-driver\Bson\ObjectModel\ObjectId.cs:line 330
            at MongoDB.Bson.ObjectId..cctor() in C:\work\10gen\mongodb\mongo-csharp-driver\Bson\ObjectModel\ObjectId.cs:line 49
       InnerException: System.InvalidOperationException
            Message=This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.
            Source=mscorlib
            StackTrace:
                 at System.Security.Cryptography.MD5CryptoServiceProvider..ctor()

Christian Csar

unread,
Sep 15, 2012, 3:49:02 PM9/15/12
to mongod...@googlegroups.com
From a security perspective, I don't think the hash algorithm used to make objectIDs much matters (one would hope that measures are in place to check for the existence of collisions in the first 3 bytes within a cluster). I am not familiar enough with FIPS 140 to know if the hash function requirements are limited to areas of security impact. If they aren't, then MongoDB will need to change that to be compliant. I take it that you are using a .NET mongo driver? It would appear necessary to use a different MD5 implementation if one wants to avoid the implications of the FIPS flag on the driver in a nonsecurity context. (It'd be best to continue using System.Security in all security contexts)
Christian

DaveC

unread,
Sep 15, 2012, 4:40:35 PM9/15/12
to mongod...@googlegroups.com
I'm not sure about the limitations of the spec, however the FIPS policy on Windows takes relatively broad strokes, restricting any use of those non-compliant algorithms on the OS, not taking into consideration the context they are being used.  As this is the .NET driver, our process could be excluded by disabling FIPS enforcement in the app.config:

<configuration> 
    <runtime> 
         <enforceFIPSPolicy enabled="false"/> 
    </runtime> 
</configuration> 

However, this is still too broad a stroke and we can't really do this and still allow our software to be considered compliant.  So the alternatives are (as you suggested) using an alternative MD5 implementation that will not be subject to the FIPS policy or to use a different algorithm altogether.  If MD5 is a hard requirement in ObjectId's for some reason, we'd need to go with the former and hope that our use of MD5 in this circumstance is permitted.  But it would be better if we could use a different algorithm altogether, as there would be no question regarding compliance, so this is the preferred approach.

Thanks,
Dave

DaveC

unread,
Sep 17, 2012, 10:15:06 PM9/17/12
to mongod...@googlegroups.com
I was hoping to hear back from the 10gen people regarding the choice of algorithm here.  Is there any significance at all to using MD5 here to create the machine hash?  Can I safely use a different algorithm?  Any chance of getting a different algorithm in the official .NET driver?

Robert Stam

unread,
Sep 17, 2012, 10:21:47 PM9/17/12
to mongod...@googlegroups.com
We created a JIRA ticket in response to this discussion:


Sorry that we neglected to respond here letting you know about the JIRA ticket.

There is no particular significance to using MD5 to create the machine portion of the ObjectId, other than that most other drivers do the same thing. All that is really needed is some function that produces a 3 byte value computed from the identity of the machine the driver is running on.

There is a small chance that changing the hash algorithm will break some people's code, but it is quite small. You would have to be doing something like comparing the machine portion of an ObjectId in an attempt to detect whether two ObjectIds were created on the same machine. Once we change hash algorithms the machine portion of an ObjectId will have a different value.

--
You received this message because you are subscribed to the Google
Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com
To unsubscribe from this group, send email to
mongodb-user...@googlegroups.com
See also the IRC channel -- freenode.net#mongodb

Christian Csar

unread,
Sep 17, 2012, 10:25:38 PM9/17/12
to mongod...@googlegroups.com
Unless I'm mistaken that 3 byte value just needs to be unique across the machines talking to Mongo at the given time and the machine ID is simply a useful way to accomplish that in a distributed fashion.

Christian

Robert Stam

unread,
Sep 19, 2012, 9:16:12 AM9/19/12
to mongod...@googlegroups.com
You are correct. The actual value of the 3 bytes doesn't really matter. They should just have a very high probability of being unique.
Reply all
Reply to author
Forward
0 new messages